简体   繁体   English

ReactJS 重新渲染不适用于 CSS

[英]ReactJS re-render is not applied on CSS

I wonder what is the reason behind of ReactJS does not force to reapply CSS to child component event if componentDidUpdate() is called.我想知道如果componentDidUpdate()被调用,ReactJS 不强制将 CSS 重新应用到子组件事件背后的原因是什么。 I did little demo and adding new box does not change color for existing boxes although numbers are changed.我做了很少的演示,尽管数字发生了变化,但添加新框不会改变现有框的颜色。

Adding Boxes Demo添加框演示

And how can I force to update it.我怎样才能强制更新它。

Thanks谢谢

The core principle behind ReactJS is that only changed objects in the DOM are updated. ReactJS 背后的核心原则是只更新 DOM 中更改的对象 This modularity gives you all kinds of speed, simplicity and abstractness advantages - even if your site contains thousands of components.这种模块化为您提供了各种速度、简单性和抽象性的优势——即使您的站点包含数千个组件。

In your example, you add a new box to the DOM and none of the other boxes are changed, ReactJS checks this automatically on every render() .在您的示例中,您向 DOM 添加了一个新框,并且没有更改其他框,ReactJS 会在每个render()上自动检查这一点。

So the answer to your question is relatively simple: if you want to other boxes to be rerendered, you need to somehow change them.所以你的问题的答案相对简单:如果你想重新渲染其他盒子,你需要以某种方式改变它们。 Otherwise ReactJS will not understand that the other boxes need to be rerendered.否则 ReactJS 将无法理解其他框需要重新渲染。 The simplest way to achieve this is to use the key property, see the documentation :实现此目的的最简单方法是使用key属性,请参阅文档

Keys help React identify which items have changed, are added, or are removed.键帮助 React 识别哪些项目已更改、添加或删除。 Keys should be given to the elements inside the array to give the elements a stable identity:应为数组内的元素提供键,以使元素具有稳定的身份:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

Now if you change the keys when you add a new item to the DOM, the objects will be rerendered because by changing the key ReactJS understands that that object needs to be rerendered.现在,如果在向 DOM 添加新项目时更改键,对象将被重新渲染,因为通过更改key ReactJS 知道该对象需要重新渲染。 You can also change other attributes to rerender the object, but changing the key is the most direct way.您还可以更改其他属性以重新渲染对象,但更改key是最直接的方法。

Additionally, you could also call forceUpdate() , see the documentation , but you'll still need to change the markup:此外,您还可以调用forceUpdate()请参阅文档,但您仍然需要更改标记:

By default, when your component's state or props change, your component will re-render.默认情况下,当您的组件的 state 或 props 发生变化时,您的组件将重新渲染。 If your render() method depends on some other data, you can tell React that the component needs re-rendering by calling forceUpdate().如果你的 render() 方法依赖于其他一些数据,你可以通过调用 forceUpdate() 告诉 React 该组件需要重新渲染。

Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate().调用 forceUpdate() 将导致在组件上调用 render(),跳过 shouldComponentUpdate()。 This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate() method of each child.这将触发子组件的正常生命周期方法,包括每个子组件的 shouldComponentUpdate() 方法。 React will still only update the DOM if the markup changes . React 仍然只会在标记更改时更新 DOM

Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render().通常你应该尽量避免使用 forceUpdate() 并且只在 render() 中从 this.props 和 this.state 中读取。

I made a fork of your project to show you how you can use the key property to force rerendering of elements我对你的项目做了一个分支,向你展示如何使用key属性来强制重新渲染元素

class App extends React.Component {
  state = {
    data: [1, 2, 3]
  };

  handler = () => {
    this.setState({ data: this.state.data.concat(this.state.data.length + 1) });
  };

  render() {
    return (
      <div>
        <button onClick={this.handler}>Add</button>
        {this.state.data.map(box => {
          return (
            <Box
              key={makeid(5)}
              click={this.handler}
              val={Math.floor(Math.random() * 10) + 1}
            />
          );
        })}
      </div>
    );
  }
}

function makeid(length) {
  var result = "";
  var characters =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  var charactersLength = characters.length;
  for (var i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}

I use the makeId function to create a random new key every I render.我使用 makeId 函数在每次渲染时创建一个随机的新密钥。 This is probably NOT the best way to do it for most use cases, this is just illustrative对于大多数用例,这可能不是最好的方法,这只是说明性的

https://codesandbox.io/s/angry-wu-8h6km https://codesandbox.io/s/angry-wu-8h6km

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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