React是否通过props渲染Component?

时间:2019-10-11 13:50:01

标签: reactjs

根据该链接:http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

render()可能由new props触发。有人可以给我一个代码示例吗?我看不到道具如何更改调用渲染!请不要通过状态更改道具;然后是setState()调用render() ...

4 个答案:

答案 0 :(得分:0)

看看shouldComponentUpdate()-这是它的签名-它返回一个布尔值。道具在那里,因此您可以比较并手动说是否应更新组件。

shouldComponentUpdate(nextProps, nextState)

答案 1 :(得分:0)

对于功能组件React.memo代替了shouldComponentUpdate,它与类组件一起使用。

const myComponent = React.memo(props => {
     ... 
     code of React.FunctionComponent
     ...
  },
  (prevProps, nextProps) => prevProps.propA === nextProps.propA
);

React.memo得到两个上面显示的参数:一个由memo包装的React.FunctionComponent和一个返回布尔值的可选函数。

当函数返回true时,将不会重新渲染组件。如果省略该函数,则其React.memo中的默认实现类似于React.PureComponent中shouldComponentUpdate的实现。例如。它对props进行了浅层比较,不同之处在于仅考虑了props,因为功能组件不存在state

答案 2 :(得分:0)

使用挂钩显示更整洁。传递给ComponentB的新道具数据会导致ComponentB的重新渲染:

import React, { useState } from 'react'
import ComponentB from '...'

const ComponentA = props => {
  const [data, setData] = useState(0)        // data = 0
  handleChangeProp = item => setData(item)  // data = 1 
  return(
    <div>
      <button onClick{() => handleChangeProp(1)}
      <ComponentB props={data} />
    </div>
  )
}

答案 3 :(得分:0)

是的,当您执行setState(newState)或传递更改的props时,组件将重新呈现,这就是为什么您无法进行突变的原因。以下无效,因为您将状态设置为突变状态。

export default function Parent() {
  const [c, setC] = useState({ c: 0 });
  console.log('in render:', c);
  return (
    <div>
      <button
        onClick={() =>
          setC(state => {
            state.c++;
            console.log('state is:', state);
            return state;
          })
        }
      >
        +
      </button>
      <Child c={c.c} />
    </div>
  );
}

该代码“不起作用”,因为按下+不会导致重新渲染,您先对状态进行了突变,然后使用相同的对象引用设置了状态,因此React不知道您进行了任何更改。

这是React检测更改的方式,您可能会认为将{c:0}{c:1}进行比较是一种更改,但是由于您进行了突变,因此实际上没有任何更改:

const a = {c:1};
a.c++;//you "changed" a but a still is a

要指示React中的更改,您必须创建一个新引用:

const a = {c:1};
const b = {...a};//b is shallow copy of a
a===b;//this is false, even though both a and b have same internal values

这意味着您还可以具有意想不到的渲染,因为您创建的对象道具可能具有相同的值,但与上次创建时的引用仍然不同。

请注意,如果Child不是纯组件,则即使<Child prop={1}也会导致Child呈现(请参阅最后的链接)。

您要避免做的是<Child prop={{c:value}},因为每次您传递prop时,即使value没有变化,它都会强制Child进行渲染,React进行虚拟DOM比较。虚拟DOM比较可能仍会检测到子虚拟DOM与上次相同,并且不会进行实际的DOM更新。

您可以做的最昂贵的事情是<Child onEvent={()=>someAction(value)}。这是因为现在虚拟DOM比较将失败,即使value和someAction不变。那是因为您每次都会创建一个新函数。

通常,您想记住在容器中创建道具的过程,here是使用react-redux钩子执行此操作的示例。 Here是一个有状态组件传递处理程序的示例。