react-redux可以在不更新parents的情况下更新child个智能组件吗?

react-redux can update child smart components without updating parents?

想象一下下面的 React 结构:

SmartComponentA -> DumbComponentB -> SmartComponentC

还假设 SmartComponentA 和 SmartComponentC 在其 mapStateToProps 函数中分别连接到状态的不同部分。

最后,假设我们在每个组件的渲染方法中放置一个 console.log

当我实际尝试此操作时,在第一次渲染时,我看到所有组件都按预期进行记录。但是,如果我更改 SmartComponentC 的数据,我只会看到一条日志消息(C 的日志消息),并且看不到 SmartComponentA 或 DumbComponentB 记录任何内容。这怎么可能? react-redux 如何让 React 在不更新 parent 的情况下更新 child?

我会假设 connect 方法中 shouldComponentUpdatethe overriding 意味着 SmartComponentA 不会得到 re-rendered(因为它的状态片没有' t 改变),因此会导致 short-circuiting 阻止 SmartComponentC 获得 re-rendered。虽然 connect 的实现与纯渲染 mixin 不同,两者都通过更改 shouldComponentUpdate 来工作,但纯渲染文档明确指出 React 将 "bail out"(正如他们所说)如果 parent 不需要 re-render:

for C2's subtree and C7, it didn't even have to compute the virtual DOM as we bailed out on shouldComponentUpdate.

source

如果我的问题仍然不清楚,这里有一些 pseudo-code 的设置,我在问为什么我可以继续输入 C 的输入并且它只记录 C 的发送到控制台而不是 A 和 B 的消息(为什么不是 short-circuiting)

//////////////////////////////////////////////

const SmartComponentA = (props) => {
  console.log('rendering SmartComponentA');

  return <DumbComponentB bData={props.bData} />;
};

const mapStateToProps = (state) => { bData: state.bData };

export default connect(mapStateToProps)(SmartComponentA);

//////////////////////////////////////////////

const DumbComponentB = (props) => {
  console.log('rendering DumbComponentB');

  return (
    <div>
      {props.bData}
      <SmartComponentC />
    </div>
  );
}

export default DumbComponentB;

//////////////////////////////////////////////

const SmartComponentC = (props) => {
  console.log('rendering SmartComponentC');

  return (
    <div>
      <input value={props.cValue} onChange={props.changeCValue} />
    </div>
  );
}

const mapStateToProps = (state) => { cValue: state.cValue };

export default connect(mapStateToProps, { changeCValue })(SmartComponentC);
//////////////////////////////////////////////

在第一次渲染时我看到了所有的日志消息,然后如果我继续输入,每次按键时我只会看到 C 的日志消息。

Prop 更改会触发 React 组件生命周期,这通常会触发每个子组件的生命周期,除非——如您所见,该过程可以被 shouldComponentUpdate 缩短。

但是 prop 更改并不是触发组件生命周期的唯一因素——状态更改也是如此。这就是连接功能的工作原理。 Connect 组件 subscribes to the store and on any store change checks to see if it will update the smart component's props (based on mapStateToProps). If so it will set it's own state 触发 Connect 组件及其子组件的生命周期函数。