0

I have a database as json file. During rendering I pick few objects at random and I want to update my global store when I map through the database, but calling dispatch in render() causes massive errors and I dont know how to proceed further.

Here is what I have without errors:

render() {
        const fakePayload = this.props.fakePayload;
        const rngPayloadId = Math.floor(Math.random() * 4);

        const payload = fakePayload.map(payload => {

            if (payload.payloadId === rngPayloadId) {

                return payload.drugsId.map(id => {
                     return <tr>
                        <td> {id}</td>
                        <td>{drugs[id].name}</td>
                        <td><input value={undefined} type="number" name="price" /></td>
                        <td><button >Send</button></td>
                        <td><button>X</button></td>
                    </tr>
                })
            }
        })

        return (
            <tbody>{payload}</tbody>
        )

And what I would want to do is something like:

 return payload.drugsId.map(id => {
   this.props.dispatch(setId(randomNumber, id)

If it matters action looks like this:

export const setId = (id, drugId) => ({  
    type: 'SET_ID',
    renderedDrugs: {
        id,
        drugId
    }
})

What do I need to learn / do to do that?

MazMat
  • 1,904
  • 3
  • 12
  • 24
  • Right now you seem to have some static data, but sooner or later that will (probably) be replaced by real database and/or server API-calls. There are many answered questions about that here, for example: https://stackoverflow.com/questions/39813984/how-to-fetch-data-through-api-in-redux (Look at the code in the JSFiddle link of the accepted answer). It touches on most of the concepts that you need to think about. Note that this is one of the harder things to do in Redux, so take time to understand it, experiment and ask questions if you get stuck. Good luck! – jonahe Sep 26 '17 at 20:37

2 Answers2

0

Perhaps it is because you are dispatching an action in render. Have you tried dispatching the action on componentDidMount()?

Based on the comment:

constructor(props){
    super(props);

    this.state = {
        rngId: 0
    };
}

render(){
    this.setState({rngId: Math.floor(Math.random() * 4)});
    ...
}

componentDidMount(){
    this.props.dispatch(....);
}
  • I didnt, because im not sure how would I access necessary data when its already rendered and not stored anywhere. – MazMat Sep 26 '17 at 09:34
  • @MazMat You can render it in `componentDidMount()` as it was suggested, then just store it in state and use when it's required. – ummahusla Sep 26 '17 at 10:49
0

Lifecycle events are a core part of React. You absolutely have to read up and understand it to a certain competency in order to use Redux. You cannot use an action inside render because an action updates your store, which updates the component, which calls render, which would also call your action, which updates your component, which calls render... I'm sure you see where this is going.

You are looking for either componentWillMount or componentDidMount. Functions inside these methods will be called once and will never call itself again while the component is mounted. Refer to the Facebook React docs on lifecycle events or other resources, like tutorials.

edit to answer your comment's question. A common paradigm for controlling rendering changes will the component is updated is to use a boolean (true/false) ternary statement, to show element or hide it (a simplification, but it works for now.) You'd be looking for something like this.

class SampleComponent {
constructor() {
  this.state = {
    show: false
  }
}
componentDidMount() {
  this.setState({show: true})
}
render() {
  return (
    <div>
      { this.state.show ? <div>mounted</div> : null }
    </div>
  )
}

There would be almost zero use cases to do something like this. componentDidMount occurs so quickly upon component mounting that you'd change this.state.show to true instantly. The html elements you were hiding using state would show as if they were never controlled with state to begin with.

Andrew
  • 7,201
  • 5
  • 25
  • 34
  • I still dont get it, I know how those components work, I just dont know how would I render something created in componentDidMount. Let's say I create a const in DiDMount that returns
    Hello
    . How to show it on screen / pass it to main render function?
    – MazMat Sep 26 '17 at 11:21
  • @MazMat updated. You'll see that the html element is 'prepped' to be shown, but is controlled by `this.state.show` as to whether or not it actually appears on the screen. – Andrew Sep 27 '17 at 20:49