React上下文API仅呈现使用已更改值的组件

时间:2019-02-23 23:08:22

标签: javascript reactjs react-context

我搞砸了上下文api,并在树中向下传递了几个值,我们称它们为val和val2。我有三个不同的组件,我们只称它们为第一,第二和第三。第二和第三将是React中Context Api的使用者。第二个将获取第一个val,第三个将获取第二个val2。现在,如果我有一个函数可以更改第二个组件使用的第一个val,那么我将获得使用val2值的第三个组件的呈现。使用redux,我不会得到这种不需要的渲染。我想知道是否有一种方法可以在React中绕过此渲染,或者redux是否仍然是获得这种性能的方法。这是我在说的一些标记:

状态和全局上下文保存在包装第一个组件的包装器中,包装器包装第二个和第三个组件。

这是第二部分:

import React, { useContext, useState } from 'react';
import {GlobalContext} from '../context/GlobalState'

const Second = () => {
  console.log("Second Rendered");
  const context = useContext(GlobalContext);
  const [inputVal, updateVal] = useState('');
  const handleSubmit = e => {
    e.preventDefault();
    context.updateVal(inputVal)
  }
  return (
    <>
      <p>{context.val}</p>
      <form onSubmit={handleSubmit}>
        <input onChange={(e) => updateVal(e.target.value)} name="val" value={inputVal} />
        <button type="submit">Update Val</button>
      </form>
    </>
  )
}

export default Second;

这是第三个组成部分:

import React, { useContext} from 'react';
import {GlobalContext} from '../context/GlobalState';

const Third = () => {
  console.log("Third Rendered")
  const context = useContext(GlobalContext);

  return (
    <p>{context.val2}</p>
  )
}

export default Third;

因此,当我更新第二个组件的值时,即使不共享这些值,第三个组件也会呈现。我知道为什么会发生这种情况,我只是好奇是否有办法阻止这种情况的发生。就像我说的那样,我没有从redux上得到这种行为,所以我想我是否应该只使用redux进行状态管理。

2 个答案:

答案 0 :(得分:0)

我知道您需要避免在<Third />组件中重新渲染。 在这种情况下,可以将React.memo与功能组件一起使用,它与纯组件具有相同的功能,但是没有类。

const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

答案 1 :(得分:0)

因此,您不能在第三个组件上使用备忘录(因为不是正在更改的道具而是上下文),但是您可以将第三个分为两部分-一个使用Context,另一个从中接收必要的值一个道具-并记住那个内在的。外部组件将重新呈现,但这只是一个包装,因此没什么大不了的。

例如:

import React, { useContext} from 'react';
import {GlobalContext} from '../context/GlobalState';

const Third = () => {
  console.log("Third Rendered")
  const context = useContext(GlobalContext);

  return (
    <ThirdBody val={context.val2} />
  )
}

const ThirdBody = React.memo(({ val }) => <p>{val}</p>)

export default Third;