React 渲染什么时候发生

React When does rendering happen

我的项目使用dvajs(基于redux和redux-saga),下面的代码是点击按钮后发送请求,通过connect改变状态,然后调用ant design组件message.error一个message.success(类似于提醒)提醒

import type { Dispatch } from 'umi';
import ProForm, { ProFormText } from '@ant-design/pro-form';
import { message } from 'antd';

const tip = (type: string, content: string) => {
  if (type === 'error') message.error(content, 5);
  else message.success(content, 5);
};

const RegisterFC: React.FC<RegisterProps> = (props) => {
  const { registerResponseInfo = {}, submitting, dispatch } = props;
  const { status } = registerResponseInfo;

  const handleSubmit = (values: RegisterParamsType) => {
    dispatch({
      type: 'register/register',
      payload: { ...values },
   });
};      

  return (
    <div>
      <ProForm
         onFinish={(values) => {
            handleSubmit(values as RegisterParamsType);
            return Promise.resolve();
    }}
       >
       <ProFormText/>
       ...
      {
        status === '1' && !submitting && (
          tip('error',
            intl.formatMessage({
              id: 'pages.register.status1.message',
              defaultMessage: 'error'
            })
          )
        )
      }
    <<ProForm>/>
    </div>
  )
}

const p = ({ register, loading }: { register: RegisterResponseInfo, loading: Loading; }) => {
  console.log(loading);
  return {
    registerResponseInfo: register,
    submitting: loading.effects['register/register'],
  };
};

export default connect(p)(RegisterFC);

当我点击按钮时,控制台提示:

Warning: Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.

状态改变时组件不会重新渲染吗?提示功能是否改变状态?

解决方案:在 return

之外调用 tip

tip 只是您调用的 function。您应该在代码的 return JSX 部分之外调用它。我认为在依赖于 statussubmittinguseEffect 挂钩中调用它是最有意义的。每次 statussubmitting 更改时效果都会运行。如果 status1 并且 submittingfalsy,那么我们调用 tip.

const RegisterFC: React.FC<RegisterProps> = (props) => {
    const { registerResponseInfo = {}, submitting, dispatch } = props;
    const { status } = registerResponseInfo;

    const handleSubmit = (values: RegisterParamsType) => {
        dispatch({
            type: 'register/register',
            payload: { ...values },
        });
    };

    React.useEffect(() => {
        if (status === '1' && !submitting) {
            tip('error',
                intl.formatMessage({
                    id: 'pages.register.status1.message',
                    defaultMessage: 'error'
                })
            );
        }
    }, [status, submitting]);

    return (
        <div>...</div>
    )
}

说明

Render methods should be a pure function of props and state

组件的渲染部分(class 组件中的 render() 或函数组件中的 return)是您创建 JSX(React HTML)标记的地方基于 propsstate 的当前值为您的组件。它不应该有任何副作用。它创建 returns JSX 就是这样。

调用 tip 是一个副作用,因为它修改了全局 antd messsage 对象。这意味着它不应该在代码的 render 部分。副作用通常在 useEffect 钩子内部处理。

您正在尝试有条件地呈现 tip 就像有条件地呈现组件一样。问题是 tip 不是组件 。函数组件是 returns JSX 元素的函数。 tip 是一个 void 函数,returns 什么都没有,所以你不能渲染它。