Redux: Memanggil store.dispatch () dari file komponen React?

Dibuat pada 19 Okt 2015  ·  10Komentar  ·  Sumber: reduxjs/redux

Saya minta maaf jika ini adalah sesuatu yang telah diselesaikan, tetapi pencarian kata kunci dalam masalah tidak menghasilkan apa pun yang membantu.

Jika saya ingin memanggil store.dispatch(someAction) dari file komponen, apakah cara yang benar untuk mengakses instance store ?

Saat ini saya memiliki yang berikut ini, yang berfungsi, tetapi saya tidak yakin itu pendekatan yang tepat:

index.jsx:

...
const store = applyMiddleware(
  loggingMiddleware, // log every action
  thunk // making API requests from actions
)(createStore)(reducer);

export {
  store
};
...

Controls.jsx

import {store} from './index.jsx';
import * as actions from './actions';
...
let clickHandler = function(node, data) {
  store.dispatch(actions.nodeClicked(data))
}
export const Controls = React.createClass({
  render: function() {
    // React component gets rendered, and it passes the clickHandler to a 
    // function that attaches it to a D3 visualization
  }
});

Apakah ada yang salah dengan mengekspor / mengimpor toko seperti ini? Saya rasa saya bisa membuat click handler sebagai bagian dari komponen React dan memanggil this.context.store , tetapi kenyataannya ada sekitar selusin event handler berbeda yang diteruskan ke visualisasi D3, jadi itu tidak terlalu praktis dalam hal ini. situasi.

question

Komentar yang paling membantu

Apakah ada yang salah dengan mengekspor / mengimpor toko seperti ini?

Ini tidak akan berfungsi jika Anda merender aplikasi di server karena Anda ingin memiliki instance store per permintaan di server. Itulah mengapa kami tidak pernah merekomendasikan pendekatan ini di dokumen.

Mengapa tidak melakukan ini saja?

import { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from './actions';

let createHandlers = function(dispatch) {
  let onClick = function(node, data) {
    dispatch(actions.nodeClicked(data))
  };

  return {
    onClick,
    // other handlers
  };
}

class Controls extends Component {
  constructor(props) {
    super(props);
    this.handlers = createHandlers(this.props.dispatch);
  }

  render() {
    // pass this.handlers anywhere you'd like
  }
}

export default connect()(Controls);

Semua 10 komentar

Lihat https://github.com/rackt/react-redux untuk metode pembantu untuk mengikat pengiriman ke komponen Anda

Secara khusus, dari https://redux.js.org/docs/basics/UsageWithReact.html

Setiap komponen yang dibungkus dengan panggilan connect () akan menerima fungsi pengiriman sebagai prop, dan status apa pun yang dibutuhkannya dari status global.

  • Komentar yang diperbarui dengan link baru ke halaman yang relevan, yang isinya sudah tidak ada

Apakah ada yang salah dengan mengekspor / mengimpor toko seperti ini?

Ini tidak akan berfungsi jika Anda merender aplikasi di server karena Anda ingin memiliki instance store per permintaan di server. Itulah mengapa kami tidak pernah merekomendasikan pendekatan ini di dokumen.

Mengapa tidak melakukan ini saja?

import { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from './actions';

let createHandlers = function(dispatch) {
  let onClick = function(node, data) {
    dispatch(actions.nodeClicked(data))
  };

  return {
    onClick,
    // other handlers
  };
}

class Controls extends Component {
  constructor(props) {
    super(props);
    this.handlers = createHandlers(this.props.dispatch);
  }

  render() {
    // pass this.handlers anywhere you'd like
  }
}

export default connect()(Controls);

@gaearon Tampak hebat, terima kasih!

@gaearon Sebenarnya, setelah mencobanya, saya mendapatkan undefined untuk this.props.dispatch .

Bagian yang relevan dari kode saya:

import React from 'react';
import {Component} from 'react';
import {connect} from 'react-redux';
import * as vizActions from './vizActions';
import viz from './lib/viz';

let createHandlers = function(dispatch) {
  return {
    click: function(DOMNode, data) {
        // Getting undefined here
        dispatch(vizActions.setSelectedNode(data));
    }
  };
}

class Viz extends Component {
  constructor(props) {
    super(props);
    console.log(this.props.dispatch); // <- Getting undefined here
    // Passing the redux dispatch to be used in handlers function
    this.handlers = createHandlers(this.props.dispatch);
  }

  componentDidMount() {
    // Create Viz
  }

  componentDidUpdate() {
    // Update Viz Data, passing in this.handlers
  }

  render() {
    return <div id="viz"></div>;
  }
};


function mapStateToProps(state) {
  return {
    // Pass the network used for the viz as a prop
    network: state.get('visualization').get('network')
  };
}

export const VizContainer = connect(mapStateToProps, vizActions)(Viz);

Namun, setelah membaca terbitan lain (https://github.com/rackt/redux/issues/239) saya menyadari bahwa saya sebenarnya mengikat tindakan saya ke this.props via connect() , jadi saya bisa cukup lewati tindakan yang diperlukan ketika saya memanggil createHandlers() . Mungkin ini bukan pendekatan terbaik tetapi berhasil sekarang:

...
let createHandlers = function(action) {
  return {
    click: function(DOMNode, data) {
                // This works now
        action(data);
    }
  };
}

class Viz extends Component {
  constructor(props) {
    super(props);
    // Passing the redux dispatch to be used in handlers function
    this.handlers = createHandlers(this.props.setSelectedNode); // passing action creator function
  }
...

Sebenarnya, setelah mencobanya, saya menjadi tidak terdefinisi untuk this.props.dispatch.

Karena Anda tidak menjalankan kode yang saya posting. Dalam kode yang saya posting connect tidak menerima parameter kedua. Anda melewati vizActions sana. Itulah mengapa Anda tidak mendapatkan dispatch . Jika Anda menghapus vizActions dari connect panggilan Anda akan mendapatkannya.

Kedua pendekatan tersebut setara, jadi pilihlah yang paling sesuai untuk Anda.

: +1: Oke, itu masuk akal sekarang. Terima kasih untuk bantuannya!

Agak telat ke pesta, tapi balas kalau-kalau nanti membantu seseorang (termasuk saya).
Jika diperlukan mapDispatchToProps kustom (parameter kedua yang dikirimkan untuk menghubungkan), tambahkan dispatch secara eksplisit sebagai salah satu kunci.

const mapDispatchToProps = (dispatch) => {
  return {
    dispatch,

    // ... other custom mapped dispatch functions ...
    myFunction: (myParam) => {
      dispatch(State.Actions...)
    },
  }
}

export default connect( mapStateToProps, mapDispatchToProps )(Viz);

Hai. Saya juga punya masalah ini.
@gaearon , saya berterima kasih atas bimbingan Anda. Saya telah menggunakan solusi Anda, tetapi saya tidak dapat memahami dan menggunakannya.
Saya tidak tahu bagaimana menggunakan this.handlers Ketika pengguna mengklik sebuah kartu, saya mengirimkan id kartu tersebut ke komponen induknya dan menjalankan aksinya.

import React , { Component } from 'react';
import { Col } from "react-bootstrap";
import { connect } from 'react-redux';
import Home from "../components/Home";
import { fetchHome, asideArticle } from "../actions/index";

let createHandlers = function(dispatch) {
    let onClick = function(node, articleId) {
        dispatch(asideArticle(articleId))
    };
    return {
        onClick
    };
}

class HomeContainer extends Component {
    constructor(props) {
        super(props);
        this.handlers = createHandlers(this.props.dispatch); 
        console.log('constructor => this.props.dispatch => Result => dispatch is undefined);
    }
    componentDidMount() {
        this.props.fetchHome();
    }

    render() {
        const { homeData, article } = this.props;


       // 
        return (
            <Col>
                <Home homeData={homeData} asideArticle={(articleId) => asideArticle(articleId) } />
            </Col>
        );
    }
}

const mapStateToProps = state => ({
    homeData : state.home,
    article: state
});

function loadData(store){
    return store.dispatch(fetchHome());
}

export default {
    loadData,
    component: connect(mapStateToProps, { fetchHome, asideArticle })(HomeContainer)
}

Bagaimana saya bisa menggunakan this.handlers dan meneruskan articleId setelah melewati event click untuk melewatinya?
Dan apa arti parameter node dalam function(node, articleId) dan apa fungsinya?

@EhsanFahami :

Ini adalah pelacak bug, bukan sistem pendukung. Untuk pertanyaan penggunaan, silakan gunakan Stack Overflow atau Reactiflux di mana ada lebih banyak orang yang siap membantu Anda - Anda mungkin akan mendapatkan jawaban yang lebih baik dengan lebih cepat. Terima kasih!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

captbaritone picture captbaritone  ·  3Komentar

benoneal picture benoneal  ·  3Komentar

mickeyreiss-visor picture mickeyreiss-visor  ·  3Komentar

olalonde picture olalonde  ·  3Komentar

parallelthought picture parallelthought  ·  3Komentar