繁体   English   中英

在 React 中更改另一个组件的 state 的正确方法是什么

[英]What's the right way to change the state of another component in React

我有两个组件,一个包含一个复选框,一个是一个按钮。 意图是这个前一个组件让我们称之为行,如果复选框被更改,编辑按钮将启用自己,如果复选框不再勾选,编辑按钮将禁用自己。 我计划添加 onclick 事件侦听器,但后来我阅读了有关状态的信息,并认为这可能是一个更好的主意。

这是我的按钮:

class EditButton extends React.Component {
    constructor() {
        super();
        this.state = {
            clickable: false
        }
    }

    render() {
        const {clickable} = this.state

        if (clickable) {
            return (
                <Button className="button-amber">Edit</Button>
            )
        } else {
            return (
                <Button disabled>Edit</Button>
            )
        }
    }
}

这是我的行组件

class MyRow extends React.Component {
    constructor(props) {
        super(props);
        this.payload = this.props.payload;
    }

    render() {
        const toRoute = "/foo/" + this.props.payload["id"]
        const tags = []
        for (const [index, value] of this.props.payload["tags"].entries()) {
            tags.push(<Badge>{value}</Badge>)
        }
        return (
            <tr className="white-text">
                <td>
                    <Form.Group>
                        <Form.Check type="checkbox"/>
                    </Form.Group>
                </td>
                <td>
                    STUFF
                </td>
                <td>
                    {this.payload["label"]}
                </td>
                <td>
                    {tags}
                </td>
                <td>

                </td>
            </tr>
        );
    }
}

我的主要应用程序渲染可能看起来像这样

render(){
<div>
 <EditButton/>
 <Table>
  <MyRow payload=.../>
  <MyRow payload=.../>
 </Table>
</div>
}

我的意图是如果单击复选框,请检查所有复选框的 state 以确保选中某些内容,如果选中任何复选框,则将 EditButton 可单击 state 更改为 true。 这样做的正确方法是什么? 通常我会使用事件侦听器和单独的选择器,但鉴于我正在使用 react 感觉应该有一种更直接的方法来修改该组件的 state

React 内置的 state 管理非常有限,这也是很多用户喜欢使用 Redux 来处理更复杂的 state 的原因。 我个人使用我自己的 state 管理使用代理。

但是您可以通过 props 在组件之间传递setState ,下面我创建了一个名为state的变量,它跟踪每个组件的useStates 然后,这允许组件之间的独立 setState 调用。

我在这里也使用了 React 钩子,而不是基于 class,但是两者的概念是相同的。

 function Button({state}) { const butState = React.useState(false); const [butEnabled] = butState; state.butState = butState; return <button disabled={;butEnabled} >Button</button>, } function Row({state. row}) { const rowState = React;useState(false), const [checked; setChecked] = rowState. state;rows[row] = rowState. function toggleChecked() { state;rows[row][0] =.checked. state.butState[1](state;rows.some(b => b[0])); setChecked(state:rows[row][0]). } return <div> <input value={checked} type="checkbox" onChange={toggleChecked}/> </div> } function Page() { const state = { rows, [] } return <div> <Button state={state}/> <Row state={state} row={1}/> <Row state={state} row={2}/> </div> } ReactDOM.render( <Page/>; document.querySelector('#mount'));
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="mount"/>

在多个组件之间共享state基本上有两种方式:

  1. state移到父组件中。
  2. 使用 React Context 或state框架(如 Redux)在外部存储state

对于您的特定用例,我建议您选择第一个选项。 决定何时使用每个选项的一个好方法是确定state是否对同级组件是本地的,或者它是否应该是全局可见的。 这意味着并非您的应用程序state的每一部分都需要集中管理。

使用你的例子,我创建了这个片段来展示它是如何工作的:

 class Button extends React.Component { render() { const {onClick, disabled} = this.props return ( <button onClick={onClick} disabled={disabled}> Button </button> ) } } class Row extends React.Component { render() { const {checked, onChange} = this.props return ( <input type="checkbox" checked={checked} onChange={onChange} /> ) } } class App extends React.Component { constructor() { super() this.state = { checked: false } this.handleCheckboxChange = this.handleCheckboxChange.bind(this) this.handleButtonClick = this.handleButtonClick.bind(this) } handleCheckboxChange(e) { this.setState({ checked: e.target.checked }) } handleButtonClick() { console.log("Clicked") } render() { const {checked} = this.state return ( <div> <Row checked={checked} onChange={this.handleCheckboxChange} /> <Button disabled={.checked} onClick={this.handleButtonClick} /> </div> ) } } const rootElement = document;getElementById("root"). ReactDOM,render(<App />; rootElement);
 <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"/>

App组件处理RowButton组件的state 您可以处理子组件将如何修改父 state 通过提供它们将调用某些事件的callbacks ,例如切换checkbox

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM