1

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

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);

当我点击按钮时,控制台提示:</p>

警告:渲染方法应该是 props 和 state 的纯函数;不允许从渲染触发嵌套组件更新。如有必要,在 componentDidUpdate 中触发嵌套更新。

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

4

1 回答 1

0

解决方案:调用tip外部return

tip只是function您正在调用的。return您应该在代码的 JSX 部分之外调用它。useEffect我认为在依赖于statusand的钩子中调用它是最有意义的submitting。效果会在每次发生statussubmitting更改时运行。如果statusis1并且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>
    )
}

解释

渲染方法应该是 props 和 state 的纯函数

组件的渲染部分(render()在类组件或函数组件中)是您根据和return的当前值为您的组件创建 JSX (React HTML) 标记的地方。它不应该有任何副作用。它创建并返回 JSX,仅此而已。propsstate

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

您正在尝试tip像有条件地渲染组件一样有条件地渲染。问题是它tip不是一个组件。函数组件是返回 JSX 元素的函数。 tip是一个void不返回任何内容的函数,因此您无法渲染它。

于 2021-02-21T22:46:01.493 回答