簡體   English   中英

React.js:如何從子級更新父級狀態

[英]Reactjs: how to update state of parent from child

我正在嘗試通過setState通過子組件更新父組件的狀態。 以下是我的父組件:

Fulllayout

import React from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import Header from '../components/header/header.jsx';
import Customizer from '../components/customizer/customizer';
import { Navbar, NavbarBrand, Collapse } from 'reactstrap';
export const settings = {
    navbarbg: 'skin1', 
    sidebarbg: 'skin6', 
    logobg: 'skin6' 
}
class Fulllayout extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            settings: settings
        };
    }
    render() {
        return (
             <div id="main-wrapper">
                <header data-navbarbg={this.state.settings.navbarbg}>
                    <Navbar expand="md" className={}></Navbar>
                </header>
                <div className="page-wrapper d-block"></div>
                <Customizer />
             </div>
        );
    }
}
export default Fulllayout;

在父母,我已經定義了一個常量設置導出。 它也在this.state給出。 在標頭中,有一個屬性data-navbarbg={this.state.settings.navbarbg}

我想動態更改其值。 因此,我有一個定制器,它作為孩子在父級中導入。 以下是子組件:

定制

import React from 'react';
import { settings } from '../../layouts/fulllayout';
import update from 'immutability-helper';

class Customizer extends React.Component {
    constructor(props) {
        super(props);
        this.navbarbgChange = this.navbarbgChange.bind(this);
        this.state = {
            settings: settings
        };
    }
    navbarbgChange(e) {
        var skin = e.currentTarget.dataset.navbarbg;
        var abc = update(this.state.settings, {
            navbarbg: { $set: skin }
        });
        this.setState({ settings: abc });
    }

    render() {
        return (
            <aside className="customizer" id="customizer">
                <a className="service-panel-toggle text-white"></a>
                <div className="customizer-body pt-3">
                    <div className="mt-3 border-bottom px-3">
                        <ul className="theme-color mb-2">
                            <li><a data-navbarbg="skin1" onClick={this.navbarbgChange}></a></li>    
                        </ul>
                    </div>
                </div>
            </aside>
        );
    }
}
export default Customizer;

從定制,通過點擊顏色,我想setState家長在給定的值data-navbarbg屬性。

如果我將此代碼放在父jsx文件中,則可以正常工作,但由於某些原因,應將此文件分隔開。

那么,我的代碼中缺少什么呢? 還是整個方法是錯誤的? 謝謝。

是否有navbarbgChangeCustomizerCustomizer navbarbgChange

您可以考慮將navbarbgChange移至Fulllayout

這樣你就可以

<li><a data-navbarbg="skin1" onClick={this.props.navbarbgChange}></a></li>

這將確保Fulllayout在其狀態下具有更新的背景。 由於settings是在父組件而不是子組件中定義的,因此這也確保了關注點之間的良好分離

在react中,您始終可以將方法從父級傳遞到子級。 讓我們在父級中編寫方法,以像這樣從子級更改父級的狀態。

class Fulllayout extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            settings: settings
        };
    }

    // This will be passed to the child component

    changeForCustomizerState() {
        this.setState({
            settings: abc
        });
    }

    changeForHeaderState() {
        this.setState({
            settings: abc
        });
    }

    render() {
        return (
             <div id="main-wrapper">
                <header chageNavbarbg={this.changeForHeaderState}>
                    <Navbar expand="md" className={}></Navbar>
                </header>
                <div className="page-wrapper d-block"></div>
                <Customizer chageNavbarbg={this.changeForCustomizerState} />
             </div>
        );
    }
}

然后onChild上的onClick只需從父級傳遞的子級調用父級方法。

render() {
        return (
            <aside className="customizer" id="customizer">
                <a className="service-panel-toggle text-white"></a>
                <div className="customizer-body pt-3">
                    <div className="mt-3 border-bottom px-3">
                        <ul className="theme-color mb-2">
                            <li><a data-navbarbg="skin1" onClick={this.props.chageNavbarbg}></a></li>    
                        </ul>
                    </div>
                </div>
            </aside>
        );
    }

可以使用回調在子級父級中完成狀態更新。 檢查下面的代碼以更好地理解

Fulllayout:

 updateState = (skin) => {
     this.setState({
          settings.navbarbg: skin
     });
}

render(){
   return(
      <div>
         <Customizer updateState={this.updateState}
      </div>
   );
}

在您的定制器中

  navbarbgChange(e){
    const skin = e.currentTarget.dataset.navbarbg;
    this.props.updateState(skin);
}

要么

Fulllayout:

 updateState = (e) => {
     const skin = e.currentTarget.dataset.navbarbg;
     this.setState({
          settings.navbarbg: skin
     });
}

render(){
   return(
      <div>
         <Customizer updateState={this.updateState}
      </div>
   );
}

定制程序:直接將父函數傳遞給onClick

  <li><a data-navbarbg="skin1" onClick={this.props.updateState}></a></li>

還要停止使用var,並主要開始使用let和const。 ECMASCRIPT本身主張避免使用var,因為其窗口范圍大。

您可以從子級調用父級的navbarbgChange(e)

在父母中:

navbarbgChange(e) {
    var skin = e.currentTarget.dataset.navbarbg;
    var abc = update(this.state.settings, {
        navbarbg: { $set: skin }
    });
    this.setState({ settings: abc });
}

<Child parentNavbarbgChange={navbarbgChange} />

navbarbgChange子調用中:

this.props.parentNavbarbgChange(e);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM