简体   繁体   中英

I can't update state for array item in react native

I have this variable

const routes = [{data : 'Home' , icon : 'home' , keep:true , txt:'Home'} , {data : 'NECard' , icon : 'card' , keep:true , txt:'Your Card'} , {data : 'Notifications' , icon : 'notifications' , color : '#EB4D4B' , count : 27 , keep:true , txt:'Notifications'} , {data : 'Requests' , icon : 'contacts' , color : '#0097E6' , count : 8 , keep:true , txt:'Requests'} , {data : 'Saved' , icon : 'bookmark' , color : '#FBC531' , count : 51 , keep:true , txt:'Saved'} , {data : 'Logout' , icon : 'ios-exit' , keep:true , txt:'Logout'}];

I set the state in the constructor

this.state = {routes : routes};

also after mounting the component I run this

componentDidMount()
  {
    this.fetchNotReadedNotis();
  }

the last step

    async fetchNotReadedNotis()
    {
       this.state.routes[2].count = 392;
       this.forceUpdate();
    }

using setState is also not working

 async fetchNotReadedNotis()
        {
           var rts = this.state.routes;
           rts[2].count = 392;
           this.setState({routes:rts});
        }

the expected is to set the routes[2] count property to 392

but no changes at all , it still 27

is there something wrong with my codes?

You should use this.setState() function to update react state. You should not mutate state directly. Read Docs here

You should not mutate state directly in React. You should use setState to update the state.

Example

class App extends React.Component {
  state = {
    routes: [
      { data: "Home", icon: "home", keep: true, txt: "Home" },
      { data: "NECard", icon: "card", keep: true, txt: "Your Card" },
      {
        data: "Notifications",
        icon: "notifications",
        color: "#EB4D4B",
        count: 27,
        keep: true,
        txt: "Notifications"
      },
      {
        data: "Requests",
        icon: "contacts",
        color: "#0097E6",
        count: 8,
        keep: true,
        txt: "Requests"
      },
      {
        data: "Saved",
        icon: "bookmark",
        color: "#FBC531",
        count: 51,
        keep: true,
        txt: "Saved"
      },
      { data: "Logout", icon: "ios-exit", keep: true, txt: "Logout" }
    ]
  };

  componentDidMount() {
    this.fetchNotReadedNotis();
  }

  fetchNotReadedNotis = async () => {
    this.setState(previousState => {
      const routes = [...previousState.routes];

      return {
        routes: [
          ...routes.slice(0, 2),
          { ...routes[2], count: 392 },
          ...routes.slice(3)
        ]
      };
    });
  };

  render() {
    return (
      <div>
        {this.state.routes.map(route => (
          <div key={route.data}>
            {route.data} {route.count}
          </div>
        ))}
      </div>
    );
  }
}

You should update state directly. Do as below:

fetchNotReadedNotis = async () => {
   var routes = Object.assign([],this.state.routes)
   routes[2].count = 392
   this.setState({routes: routes},() => { this.forceUpdate() })
}

Detail: Your fetchNotReadedNotis wasn't binded to your component, so it can't mutate the state of it. The this reference inside your method wasn't your component. Now, doing the fetchNotReadedNotis = async () => {} , it is binded to your component, and then, it will mutate the state properly.

 class App extends React.Component { constructor(props){ super(props) this.state = { routes: [{data : 'Home' , icon : 'home' , keep:true , txt:'Home'} , {data : 'NECard' , icon : 'card' , keep:true , txt:'Your Card'} , {data : 'Notifications' , icon : 'notifications' , color : '#EB4D4B' , count : 27 , keep:true , txt:'Notifications'} , {data : 'Requests' , icon : 'contacts' , color : '#0097E6' , count : 8 , keep:true , txt:'Requests'} , {data : 'Saved' , icon : 'bookmark' , color : '#FBC531' , count : 51 , keep:true , txt:'Saved'} , {data : 'Logout' , icon : 'ios-exit' , keep:true , txt:'Logout'}] } } componentDidMount(){ this.fetchNotReadedNotis(); } fetchNotReadedNotis = () => { var routes = Object.assign([],this.state.routes) routes[2].count = 392 this.setState({routes: routes},() => { this.forceUpdate()}) } render() { return( <div> {this.state.routes.map(route => <p> {route.data} {route.count}</p>)} </div> ) } } ReactDOM.render(<App/>,document.getElementById('root')); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="root"> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM