1

I want to update the state of a main component from the "A" component then push it to "B" component and then use it render to dynamically populate boxes.

Main Component :

constructor() {
        super();
        this.state = {
            events:[],
            alerts:[],
        };

      }
  addEvent = newEvent => this.setState(state => {
    const {events} = this.state
    return [...events, newEvent]
  });

  addAlert = newAlert => this.setState(state =>{
    const {alerts} = this.state
    return [...alerts, newAlert]
  });

render(){
    const {events} = this.state
    const {alerts} = this.state
    console.log(events) // events are empty even after I pass and store it 
                        //   in SearchFlight Component  
    return(
        <div >

                <SearchFlight events={events} alerts={alerts} addAlert={this.addAlert} addEvent={this.addEvent} />
                <Events events={events}/>
                <Alerts />
            </div>

    );

}

SearchFlight Component(A component) :

handleSubmit= event =>{
        const {addEvent} = this.props
        const {addAlert} = this.props
        event.preventDefault();

        var newEvents=[];
        var newAlerts=[];


                 var singleEvent={
                   event_name:'home',
                   date_time:'12-08-18 12:45 AM',
                 };

                  newEvents.push(singleEvent);

                  newAlerts.push("Remove the luggage tag");

           addAlert(newAlerts);  
           addEvent(newEvents);

    }

Then I have Event Component(B Component) which right now just have render method. I want to get the updated events here.

Problem : Getting empty events when I did console.log(events) in render method of Main Component

Kramer
  • 389
  • 8
  • 34

3 Answers3

1

The State is private to the component. If the state is passed to the child component using props, again props should not be mutated as per the reactjs guidelines.

You can only read the value in Component A from the props and modify that value to pass it further to the nested components. But can't modify the state of the Main Component from A.

Check this out: https://reactjs.org/docs/state-and-lifecycle.html

onejeet
  • 1,191
  • 6
  • 14
1

You aren't using the setState correctly in addEvents and addAlerts method. the callback pattern of setState needs to return an object

addEvent = newEvent => this.setState(state => {
    const {events} = state
    return { events: [...events, ...newEvent]}
  });

  addAlert = newAlert => this.setState(state =>{
    const {alerts} = state
    return {alerts: [...alerts, ...newAlert]
  });

Also since events is an array of objects your need to iterate on them to render. Refer How to render an array of objects in React? answer for more details on how to do that

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • In console I got my events in Main Component but when I did `this.props.events` to receive it since I am passing props from Main Component `` . I received this error **Uncaught Error: Objects are not valid as a React child (found: object with keys {event_name, date_time}). If you meant to render a collection of children, use an array** – Kramer Nov 30 '18 at 06:44
  • I received this error when again I passed events to B component – Kramer Nov 30 '18 at 06:46
  • How are you rendering the events in component B. The errors seems to be related to that – Shubham Khatri Nov 30 '18 at 06:51
  • this way `
    {this.props.events}
    ` but since events is jsonarray therefore that's why I am getting the error I might need to iterate can you post on that?
    – Kramer Nov 30 '18 at 06:53
  • Updated the post – Shubham Khatri Nov 30 '18 at 06:55
  • Perfect! Lastly if I want to format the values I received how will I loop inside a div because I want boxes like feature event_name(key1) as a button then next line date_time(key2) – Kramer Nov 30 '18 at 07:12
  • You would loop over the events array which gives you an event object. Now you can choose to render each property as you want like `
    {event.event_name}
    `
    – Shubham Khatri Nov 30 '18 at 07:16
  • I am not able to empty this list like it is appending again and again – Kramer Nov 30 '18 at 10:24
  • Please ask another question with the details about your current problem. Comments will get too messy discussing an unrelated issue here – Shubham Khatri Nov 30 '18 at 10:25
  • https://stackoverflow.com/questions/53555834/empty-the-state-of-parent-component-from-button-in-child-component – Kramer Nov 30 '18 at 10:38
0

As pointed out by OneJeet React is all about top-down approach and the child component should not be aware if a parent component is stateless or stateful.

Passing the setState as a function and allowing the child component to call it, is bad practice. One way is to use redux and eliminate the need to update parent state from child component or re-structure the whole thing in a different way.

Arshanwer
  • 1
  • 1