如果从React挂钩中从许多来源获取信息,如何防止重新渲染?

时间:2019-09-10 06:01:39

标签: reactjs react-hooks

我在React Native中使用react hooks。 我的问题是,初始化状态的useState函数会重新呈现。 因此,如果我将状态设置为如下

    const [A, setA] = useState(false);
    const [B, setB] = useState(false);
    const [C, setA] = useState(false);

    // ...

    const testFunc = () => {
        setA(true);
        setB(true);
        setC(true);
    }


已编辑 我认为例子是错误的。 这是另一个例子。

const useFetch(coords) {
    const [example, setExample] = useState([])
    const [checker, setChecker] = useState(false);

    const fetchData = () => {
        axios.fetch(`url+${coords.latitue}+${coords.longitude}`).then(){
            setExample(res.data());
            setChecker(true);
        }
    }

    useEffect(() => {
        fetchData();
    }, [coords])

    return example;
}

const useLocation = () => {
    ...
    return coords;
}

const App = () => {
    const coords = useLocation();
    const example = useFetch(coords); // example is undefined.
    const [data, setData] = useState(example); // data is undefined.
}

与我使用set函数一样,它会导致许多重新渲染。 这是自然的事吗? 如果我不想重新渲染,就不能多次使用set函数吗?

3 个答案:

答案 0 :(得分:3)

您不能直接做到这一点。我将为您推荐两种解决方案。

解决方案1:将状态组合到一个对象中。

const [value, setValue] = useState({A: false, B: false, C: false});

// ...

const testFunc = () => {
    setValue({A: true, B: true, C: true});
}

解决方案2:另一个解决方案是useReducer

const [state, setState] = useReducer(
  (state, newState) => ({...state, ...newState}),
  {A: false, B: false, C: false}
);

// ...

const testFunc = () => {
    setState({A: true, B: true, C: true});
}

在这里,我实现了您的另一个示例:https://stackblitz.com/edit/react-usestate-wcjshg

希望这对您有帮助!

答案 1 :(得分:1)

如果在基于React的事件之外触发

React不会批处理状态更新。这意味着,如果要批量处理状态更新,则需要将其包装在事件处理程序上,例如onClick

如果您的本地组件状态不重要,并且/或者不能使用事件处理程序,那么我建议您使用useReducer,因为您可以在其中批量更新状态。

  

这似乎是正常的React行为。如果您要在类组件中多次调用setState(),则其工作方式完全相同。

     

如果从基于React的事件中触发状态更新,例如按钮单击或输入更改,React当前将批处理状态更新。如果更新是在React事件处理程序外部触发的,例如setTimeout(),它将不会批量更新。

     

我认为长期计划总是批量处理事件,但不确定细节

来源: https://github.com/facebook/react/issues/14259#issuecomment-439632622 https://github.com/facebook/react/issues/14259#issuecomment-468937068

答案 2 :(得分:1)

如其他答案所述,如果在基于React的事件之外触发状态更新(例如,在then中),React不会批处理状态更新,解决方案之一是将您的状态合并到一个对象中并调用setState一次。但是,如果您希望保持状态分离,解决方案是使用ReactDOM.unstable_batchedUpdates像这样:

    const fetchData = () => {
        axios.fetch(`url+${coords.latitue}+${coords.longitude}`).then(() => {
            ReactDOM.unstable_batchedUpdates(() => {
                setExample(res.data());
                setChecker(true);
            });
        });
    }

丹·阿布拉莫夫here推荐