加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactjs – 当子组件返回新内容时,是否重新呈现父组件?

发布时间:2020-12-15 16:15:51 所属栏目:百科 来源:网络整理
导读:只要我知道,当父组件的状态或props改变时,子组件将被重新呈现. 但我不知道反之亦然. 这是一个代码. usePromise.js(定制钩子) import { useEffect,useReducer } from 'react';const reducer = (state,action) = { switch (action.type) { case 'RESOLVED': re
只要我知道,当父组件的状态或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;
}

usePromiseSample.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)组件的状态正在改变四次.

但似乎父级(usePromiseSample.js)也被重新渲染四次,因为测试记录了四次.

我怎样才能轻易理解这种情况?

解决方法

usePromise不是子组件,而是自定义钩子.钩子本身在usePromise内部调度动作时不会被重新渲染,但是使用它的组件是.

如果在另一个组件中渲染UsePromiseSample,您将看到当UsePromiseSample为父级时,父级不会重新渲染.

const { useEffect,useReducer } = React;

const reducer = (state,action) => {
  switch (action.type) {
    case 'RESOLVED':
      return { ...state,resolved: action.diff,loading: false };
    case 'ERROR':
      return { ...state,loading: false };
    default:
      return state;
  }
};

function usePromise(promiseCreator,deps = []) {
  const [state,{
    resolved: null,loading: true,error: null
  });

  const process = () => {
     promiseCreator()
       .then(result => {
         dispatch({ type: 'RESOLVED',diff: result });
       })
       .catch(e => {
        dispatch({ type: 'ERROR',diff: e });
       });
  };

  useEffect(() => {
    process();
  },deps);

  return state;
}

const wait = () => {
  return new Promise(resolve =>
    setTimeout(() => resolve('Hello hooks!'),3000)
  );
};

const UsePromiseSample = () => {
  const { resolved,error } = usePromise(wait);

  console.log('UsePromiseSample rendered')

  if (loading) return <div>loading...</div>;
  if (error) return <div>error happened!</div>;
  if (!resolved) return null;

  return <div>{resolved}</div>;
};

const App = () => {
  console.log('App rendered')

  return <UsePromiseSample />
}

ReactDOM.render(<App />,document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读