Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get data from Redux Store after data has been added

I am using a boilerplate called trufflebox's react-auth where

  1. getWeb is called on loading the page (Link to code)
  2. which creates the web3 object (Link to Code)
  3. and stores web3 in the Redux store (Link to code)

Problem: When I retrieve the web3 object from the Redux store, it is undefined, most likely because web3 has not been created yet in Step 2 described above.

What should be the correct way to retrieve web3 from the Redux store only after it has been set?

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

Everything works if I retrieve web3 again without going to the Redux store:

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
like image 724
Nyxynyx Avatar asked Nov 28 '25 21:11

Nyxynyx


1 Answers

Resolve the promise just after creating the store

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;

In you ./index.js (where you are rendering the whole app) consider to use Provider component as wrapper to pass store behind the seen and have a singleton store.

src/index.js

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

        ReactDOM.render(

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

Now, in your component, connect HOC will do everything , see comments below :

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 
like image 132
Abdennour TOUMI Avatar answered Dec 01 '25 12:12

Abdennour TOUMI