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 部分之外调用它。我认为在依赖于 status
和 submitting
的 useEffect
挂钩中调用它是最有意义的。每次 status
或 submitting
更改时效果都会运行。如果 status
是 1
并且 submitting
是 falsy,那么我们调用 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)标记的地方基于 props
和 state
的当前值为您的组件。它不应该有任何副作用。它创建 returns JSX 就是这样。
调用 tip
是一个副作用,因为它修改了全局 antd
messsage
对象。这意味着它不应该在代码的 render
部分。副作用通常在 useEffect
钩子内部处理。
您正在尝试有条件地呈现 tip
就像有条件地呈现组件一样。问题是 tip
是 不是组件 。函数组件是 returns JSX 元素的函数。 tip
是一个 void
函数,returns 什么都没有,所以你不能渲染它。
我的项目使用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 部分之外调用它。我认为在依赖于 status
和 submitting
的 useEffect
挂钩中调用它是最有意义的。每次 status
或 submitting
更改时效果都会运行。如果 status
是 1
并且 submitting
是 falsy,那么我们调用 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)标记的地方基于 props
和 state
的当前值为您的组件。它不应该有任何副作用。它创建 returns JSX 就是这样。
调用 tip
是一个副作用,因为它修改了全局 antd
messsage
对象。这意味着它不应该在代码的 render
部分。副作用通常在 useEffect
钩子内部处理。
您正在尝试有条件地呈现 tip
就像有条件地呈现组件一样。问题是 tip
是 不是组件 。函数组件是 returns JSX 元素的函数。 tip
是一个 void
函数,returns 什么都没有,所以你不能渲染它。