当状态改变时,对文本字段做出反应 onChange 更新整个组件
Posted
技术标签:
【中文标题】当状态改变时,对文本字段做出反应 onChange 更新整个组件【英文标题】:react onChange on text field update whole component when state is changed 【发布时间】:2020-05-12 05:39:17 【问题描述】:我有一个功能组件并使用反应挂钩来管理状态。
只要我在 textField 中添加 onChange(在材质 UI 中输入),整个组件就会重新渲染,当我在 textField 中删除 onChange 时,它不会重新渲染
<TextField
id='outlined-basic'
label='Outlined'
variant='outlined'
fullWidth
onChange=e =>
setChannelUrl(e.target.value);
/>
上图是组件在我没有传递任何道具的情况下重新渲染。
我删除 setChannelUrl(e.target.value);
后,一切正常。
setChannelUrl 是 react useState Hooks
const [channelUrl, setChannelUrl] = useState('');
useEffect(() =>
console.log('runnedddd');
return () => ;
, []);
const classes = useStyle();
return (
<Grid container spacing=2 className=classes.root>
<Grid item md=6>
<Typography variant='h6' color='primary' className=classes.button>
Please Enter Your Channel Url
</Typography>
<TextField
id='outlined-basic'
label='Outlined'
variant='outlined'
fullWidth
onChange=e =>
setChannelUrl(e.target.value);
/>
<Button fullWidth color='primary' variant='contained'>
large
</Button>
</Grid>
<Grid item md=6>
<Paper elevation=2 className=`flex flexColumn $classes.w100`>
<Avatar alt='Remy Sharp' src=''>
H
</Avatar>
<Typography variant='body' align='center'>
Hitesh Choudary
</Typography>
<Button
fullWidth
color='primary'
variant='contained'
className=classes.button
>
Save It
</Button>
<Button
fullWidth
color='secondary'
variant='contained'
className=classes.button
>
No, its not mine
</Button>
<Stats />
</Paper>
</Grid>
</Grid>
);
;
统计组件
import React from 'react';
const Stats = props =>
console.log(props);
return <div></div>;
;
export default Stats;
我正在使用函数组件和箭头函数
【问题讨论】:
这是正确的行为。当你改变使用钩子的状态时,状态所在的组件会重新渲染 @DennisVash 这个问题很清楚,我们不需要一个例子来理解这一点。这是基本的反应行为 @jsRook 那么有什么问题吗?你还在为某事感到困惑吗? 那么告诉我们日志来自哪里,谁是父级,结构是什么,期望的行为是什么? 我认为这里的简短回答是“是的,每次更改状态时整个组件都会重新渲染”,这就是它的工作原理,很好,没有什么好担心的 【参考方案1】:Stats
组件渲染到其父渲染。
当用户在文本字段中输入时父级呈现,onChange
通过setChannelUrl
更新声明。
您可以用React.memo
记忆Stats
,这将防止不希望的渲染:
如果你的函数组件在给定相同的 props 的情况下呈现相同的结果,你可以将它包装在对 React.memo 的调用中,以便在某些情况下通过记忆结果来提高性能。这意味着 React 将跳过渲染组件,并重用上次渲染的结果。
const Stats = () =>
// Won't log on parent render
console.log('rendered');
return <div></div>;
;
export default React.memo(Stats);
【讨论】:
这是一个很好的答案,我只是提醒一下,不一定建议使用memo
阻止渲染。在可以防止数百或数千次渲染的情况下,它可以作为性能优化。在大多数情况下,让 React 渲染很好,也更容易推理以上是关于当状态改变时,对文本字段做出反应 onChange 更新整个组件的主要内容,如果未能解决你的问题,请参考以下文章