当状态改变时,对文本字段做出反应 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 更新整个组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在不改变状态的情况下对 redux 操作做出反应

即使道具没有改变,为啥还要对重新渲染组件做出反应?

数据更改时如何对 UIControl 调整大小做出反应

如何使 .svg 图标对禁用状态做出反应并更改其颜色?

当 useState 改变 react-complex-tree 不重新渲染时做出反应

反应:onChange 不更新输入字段的值