【问题标题】:Get data from Redux Store after data has been added添加数据后从 Redux Store 获取数据
【发布时间】:2018-04-24 18:56:10
【问题描述】:

我在哪里使用a boilerplate called trufflebox's react-auth

  1. getWeb 在加载页面时被调用 (Link to code)
  2. 创建 web3 对象 (Link to Code)
  3. 并在 Redux 存储中存储 web3 (Link to code)

问题:当我从 Redux 存储中检索 web3 对象时,它是 undefined,很可能是因为在上述步骤 2 中尚未创建 web3。 p>

只有在设置后才能从 Redux 存储中检索 web3 的正确方法应该是什么?

layouts/test/Test.js

import React, { Component } from 'react';
import store from '../../store';


class Test extends Component {

    componentWillMount() {
        this.setState({
            web3: store.getState().results.payload.web3Instance
        })
        this.instantiateContract()
    }

    instantiateContract() {
        console.log(this.state.web3)                             // UNDEFINED!!
    }


    render() {
        return (
            <h1>Test</h1>
        )
    }
}

export default Test

如果我再次检索 web3 而不去 Redux 商店,一切正常:

import React, { Component } from 'react';
import getWeb3 from '../../util/web3/getWeb3';


class Test extends Component {

    componentWillMount() {
        getWeb3
        .then(results => {
            this.setState({
                web3: results.payload.web3Instance
            })
            this.instantiateContract()
        })
    }


    instantiateContract() {
        console.log(this.state.web3)
    }


    render() {
        return (
            <h1>Test</h1>
        )
    }
}

export default Test

【问题讨论】:

  • 你能解决这个问题吗?我在下面的回答是否能够帮助您指出正确的方向?请尽可能分享您在这方面的进展。

标签: javascript reactjs redux react-redux web3js


【解决方案1】:

在创建商店后立即解决承诺

src/store.js

        import getWeb3 from './util/web3/getWeb3';
        import { createStore } from 'redux';

        //... prepare middlewares and other stuffs , then : create store
        const store = createStore(/*....configure it as you want..*/);

        // Just after creating store, here the engineering:

        getWeb3.then(results => {
          // Assuming you have suitable reducer
          // Assuming the reducer put the payload in state and accessible via "getState().results.payload.web3Instance"
          store.dispatch({ type: 'SAVE_WEB3', payload: results.payload.web3Instance });
        });


        export default store;

在你 ./index.js(你正在渲染整个应用程序的地方)考虑使用 Provider 组件作为包装器来传递所见的存储并拥有一个单例存储。

src/index.js

        import { Provider } from 'react-redux';
        import store from './store';

        ReactDOM.render(

          <Provider store={store}>
            <Test />
          </Provider>
        )

现在,在您的组件中,connect HOC 将做所有事情,请参阅下面的 cmets:

src/.../Test.js

        import { connect } from 'react-redux';


        class Test extends Component {
           // No need any lifecyle method , "connect" will do everything :)

            render() {
                console.log(this.props.web3)      
                return (
                    <h1>Test</h1>
                )
            }
        }
        // Retrieve from Redux STATE and refresh PROPS of component

        function mapStateToProps(state) {
          return {
            web3: state.results.payload.web3Instance  // since you are using "getState().results.payload.web3Instance"
          }
        }
        export default connect(mapStateToProps)(Test); // the awesome "connect" will refresh props 

【讨论】:

    【解决方案2】:

    也许尝试在componentWillReceiveProps 阶段调用instantiateContract。看看下面...

    componentWillMount() {
      this.setState({
        web3: store.getState().results.payload.web3Instance
      });
    }
    
    instantiateContract() {
      console.log(this.state.web3); // hopefully not undefined                           
    }
    
    componentWillReceiveProps(nextProps) {
      if(nextProps.whatever) {
        this.instantiateContract();
      }
    }
    
    render() {
      return (
        <h1>Test</h1>
      )
    }
    

    nextProps.whatever 是您从 redux 映射的内容(不完全确定您的详细信息是什么)。理想情况下,这会反馈到您的组件中,当值填充或更改时,您然后调用您的函数


    此外,我在这里看到很多状态管理与我期望通过props 看到的相反。如果考虑到您的应用程序架构,componentWillReceiveProps(nextProps) 不是一个好的钩子,componentDidUpdate(prevProps, prevState) 可能是一个可行的替代方案。

    【讨论】:

    • 您是否建议先在路由定义所在的index.js 中检索web3 对象,然后将其作为prop 传递给Test 组件?
    • 无论web3 是什么,这是您在运行应用程序之前 需要的一次性应用程序设置内容吗?如果是这样,那么完全。我不知道你的应用程序的完整架构,但根据你的一些命名,我倾向于我的预感是真实的。如果可以的话,我会完全放弃.setState。调度您的活动,通过 reducer 在您的商店中设置值,映射它,然后收工。如果这是一个真正的异步调用,您将需要利用生命周期事件挂钩来检查它,就像我上面提到的那样。如果您能够在应用运行之前制作它,那就更好了,因为您已经将它挂载了
    • @Nyxynyx 你能解决这个问题吗?请尽可能分享您在这方面的进展。
    猜你喜欢
    • 2021-11-05
    • 2017-08-10
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    • 2020-06-04
    • 2020-06-04
    • 2021-09-27
    • 1970-01-01
    相关资源
    最近更新 更多