简体   繁体   中英

React not reordering array of components on render

I am trying to render a list of components in order with react, the component is updating this array of elements but is not re-ordering them.

Pseudo code;

class Form extends Component {
  //
  // .... other initialization code and logic
  //

  updatePositions() {
    //
    // re-order this.state.page.page_contents
    //
    this.setState({ page: this.state.page });
  }

  renderContents() {
    return this.state.page.page_content.map((c, i) => {
      return (<ContentItem
        key={ i }
        content={ c }
      />);
    });
  }

  render() {
    return (
      <div className="row">
        <div className="medium-12 columns">
          { this.renderContents() }
        </div>
      </div>
    );
  }
}

If i log out the results of page.page_content the items are being reordered in the array, however the form render is not re-rendering the contents in its new order

You shouldn't be using array indices as keys if your array order is subject to change. Keys should be permanent, because React uses the keys to identify the components, and if a component receives a key that previously belonged to a different component, React thinks it is the same component as before.

Create unique keys for your elements that are permanent to those elements.

you could try to force update

 renderContents() {
          this.forceUpdate();           
          return this.state.page.page_content.map((c, i) => {
              return (<ContentItem
                key={ i }
                content={ c }
              />);
            });

          }

Don't mutate this.state , directly. Bring it into a new variable and then add it back into state.

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

from: https://reactjs.org/docs/react-component.html

Instead, you should try:

  updatePositions() {
    const page_contents = [...this.state.page.page_contents]
    // re order page_contents
    this.setState({ page: { page_contents });
  }
renderContents() {
    return this.state.page.page_content.map((c, i) => {
      return (<ContentItem
        key={ i }
        content={ c }
      />);
    });
  }

it's your code here - key={i} i is not changing so it will not re-render the component - if you want to re-render the component - please make sure that - key should change.

renderContents() {
    return this.state.page.page_content.map(c => {
      return (<ContentItem
        key={ c }
        content={ c }
      />);
    });
  }

c is content - if it's change then Component will re-render

this.setState({ page: this.state.page }) it's wrong - ur trying to set the same value in same variable again .

class Form extends Component {
  //
  // .... other initialization code and logic
  //

  updatePositions() {
    //
    // re-order this.state.page.page_contents
    //
    this.setState({ page: newValueFromAPI.page });
  }

  render() {
    const { page: { page_content } } = this.state
    return (
      <div className="row">
        <div className="medium-12 columns">
          { page_content.length > 0 && (
             page_content.map(c => <ContentItem key={c} content={c}/>)
          )}
        </div>
      </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