在 React.js 中触发子项重新渲染

新手上路,请多包涵

Parent( MyList 在我的示例中)组件通过 Child( MyComponent )组件呈现数组。父决定更改数组中的属性,React 触发子重新渲染的方式是什么?

在调整数据后,我在 Parent 中想到的是 this.setState({}); 。这是触发更新的 hack 方式还是 React 方式?

JS 小提琴: https ://jsfiddle.net/69z2wepo/7601/

 var items = [
  {id: 1, highlighted: false, text: "item1"},
  {id: 2, highlighted: true, text: "item2"},
  {id: 3, highlighted: false, text: "item3"},
];

var MyComponent = React.createClass({
  render: function() {
    return <div className={this.props.highlighted ? 'light-it-up' : ''}>{this.props.text}</div>;
  }
});

var MyList = React.createClass({
  toggleHighlight: function() {
    this.props.items.forEach(function(v){
      v.highlighted = !v.highlighted;
    });

    // Children must re-render
    // IS THIS CORRECT?
    this.setState({});
  },

  render: function() {
    return <div>
      <button onClick={this.toggleHighlight}>Toggle highlight</button>
      {this.props.items.map(function(item) {
          return <MyComponent key={item.id} text={item.text} highlighted={item.highlighted}/>;
      })}
    </div>;
  }
});

React.render(<MyList items={items}/>, document.getElementById('container'));

原文由 Djam 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 359
2 个回答

这里的问题是您将状态存储在 this.props 而不是 this.state 。由于此组件正在发生变化 itemsitems 处于状态并且应存储在 this.state 中。 (这是 一篇关于道具与状态的好文章。)这解决了您的渲染问题,因为当您更新 items 时,您将调用 setState ,这将自动触发重新渲染。

这是您的组件使用状态而不是道具的样子:

 var MyList = React.createClass({
    getInitialState: function() {
        return { items: this.props.initialItems };
    },

    toggleHighlight: function() {
        var newItems = this.state.items.map(function (item) {
            item.highlighted = !item.highlighted;
            return item;
        });

        this.setState({ items: newItems });
    },

    render: function() {
        return (
            <div>
                <button onClick={this.toggleHighlight}>Toggle highlight</button>
                { this.state.items.map(function(item) {
                    return <MyComponent key={item.id} text={item.text}
                             highlighted={item.highlighted}/>;
                }) }
            </div>
        );
    }
});

React.render( <MyList initialItems={initialItems}/>,
              document.getElementById('container') );

请注意,我将 items 道具重命名为 initialItems ,因为它清楚地表明 MyList 会改变它。这是 文档推荐的

你可以在这里看到更新的小提琴: https ://jsfiddle.net/kxrf5329/

原文由 Jordan Running 发布,翻译遵循 CC BY-SA 3.0 许可协议

我找到了一个很好的解决方案,它使用 key 属性通过 React Hook 重新渲染。如果我们更改了子组件或 React 组件的某些部分的 关键 属性,它将完全重新渲染。当您需要重新渲染 React Component 的某些部分或重新渲染子组件时,它将使用。这是一个例子。我将重新渲染完整的组件。

 import React, { useState, useEffect } from "react";
import { PrEditInput } from "./shared";

const BucketInput = ({ bucketPrice = [], handleBucketsUpdate, mood }) => {
  const data = Array.isArray(bucketPrice) ? bucketPrice : [];
  const [state, setState] = useState(Date.now());
  useEffect(() => {
    setState(Date.now());
  }, [mood, bucketPrice]);
  return (
    <span key={state}>
      {data.map((item) => (
        <PrEditInput
          key={item.id}
          label={item?.bucket?.name}
          name={item.bucketId}
          defaultValue={item.price}
          onChange={handleBucketsUpdate}
          mood={mood}
        />
      ))}
    </span>
  );
};

export default BucketInput;

原文由 Tofazzal haque 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题