3

我正在使用一个名为 trufflebox's react-auth 的样板,其中

  1. getWeb在加载页面时调用(链接到代码
  2. 创建web3对象(链接到代码
  3. 并存储web3在 Redux 商店中(链接到代码

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

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

布局/测试/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
4

2 回答 2

4

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

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>
        )

现在,在您的组件中,connectHOC 将做所有事情,请参阅下面的评论:

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 
于 2017-11-11T19:08:26.970 回答
2

也许尝试instantiateContractcomponentWillReceiveProps阶段调用。看看以下...

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>
  )
}

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


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

于 2017-11-11T18:55:57.170 回答