【发布时间】:2019-03-10 12:51:10
【问题描述】:
据我所知,当父组件的state 或props 更改时,子组件正在重新渲染。
但我不知道反之亦然。
这是一个代码。
usePromise.js(定制的钩子)
import { useEffect, useReducer } from 'react';
const reducer = (state, action) => {
switch (action.type) {
case 'RESOLVED':
return { ...state, resolved: action.diff };
case 'LOADING':
return { ...state, loading: action.diff };
case 'ERROR':
return { ...state, resolved: action.diff };
default:
return state;
}
};
export default function usePromise(promiseCreator, deps = []) {
const [state, dispatch] = useReducer(reducer, {
resolved: null,
loading: false,
error: null
});
const process = async () => {
dispatch({ type: 'LOADING', diff: true });
try {
const result = await promiseCreator();
dispatch({ type: 'RESOLVED', diff: result });
} catch (e) {
dispatch({ type: 'ERROR', diff: e });
}
dispatch({ type: 'LOADING', diff: false });
};
useEffect(() => {
process();
}, deps);
return state;
}
使用PromiseSample.js
import React from 'react';
import usePromise from './usePromise';
const wait = () => {
return new Promise(resolve =>
setTimeout(() => resolve('Hello hooks!'), 3000)
);
};
const UsePromiseSample = () => {
const { resolved, loading, error } = usePromise(wait);
console.log('test')
if (loading) return <div>loading...</div>;
if (error) return <div>error happened!</div>;
if (!resolved) return null;
return <div>{resolved}</div>;
};
export default UsePromiseSample;
从上面的代码可以看出,child(usePromise.js) 组件的状态变化了四次。
但似乎 parent(usePromiseSample.js) 也被重新渲染了四次,因为 test 被记录了四次。
我怎样才能轻松理解这种情况?
【问题讨论】:
-
usePromise不是子组件,而是自定义钩子。钩子本身不会被重新渲染,但使用它的组件会。如果您在另一个组件中渲染UsePromiseSample,您会看到当UsePromiseSample存在时父级没有重新渲染。 -
我不确定我们是否仍然可以使用带有钩子的
parent/child词汇。这是依赖关系的问题;usePromiseSample依赖于usePromise,因此如果usePromise状态发生变化,它将重新加载。 -
谢谢@Tholle,但是那个钩子本身不是没有被重新渲染吗?我很困惑,因为如果我们将 console.log() 添加到 UsePromise.js,它也会注销四次。
-
@soywod 感谢您的重要更正。所以我们可以使用父/子这个词来表示类组件,但不能用于功能组件,对吧?
-
这不是关于类或函数组件,而是关于钩子。这是一种不同的方法。你不能说
usePromise是usePromiseSample的孩子。但是usePromiseSample使用(或依赖于)usePromise。
标签: reactjs react-hooks