ReactJS: Как изменить значение свойства состояния в компоненте, когда значение свойства состояния в другом компоненте является определенным значением - PullRequest
0 голосов
/ 14 апреля 2020

Я работаю над приложением React и использую Redux для хранения состояния. У меня есть следующий код.

menu.component.jsx:

import React, { Component } from 'react';
import { connect } from 'react-redux';

import MenuCategory from '../../components/menu-category/menu-category.component'
import NewCategoryButton from '../../components/new-category-button/new-category-button.component';
import EditMenuButton from '../../components/edit-menu-button/edit-menu-button.component';

import './menu.styles.scss';

class MenuPage extends Component {

    state = {
        menuEditable: false
    }

    render() {

        return (
            <div className='menu-page'>
                {this.props.menu ? this.props.menu.map(category => <MenuCategory key={category._id} {...category} />) : null}
                <div className='edit-menu-buttons'>
                    <div className='menu-button'>
                        {this.props.currentUser ? <NewCategoryButton /> : null}
                    </div>
                    <div className='menu-button'>
                        {this.props.currentUser ? <EditMenuButton /> : null}
                    </div>
                </div>
            </div>
        )
    }
}

const mapStateToProps = state => ({
    currentUser: state.user.currentUser,
    menu: state.menu
})

export default connect(mapStateToProps)(MenuPage);

edit-menu-button.component.jsx:

import React, { Component } from 'react';
import { connect } from 'react-redux';

import Button from '../button/button.component';

class EditMenuButton extends Component {

    state = {
        text: "Edit Menu"
    }

    changeText = () => {
        const { text } = this.state;
        if(text === "Edit Menu") {
            this.setState({text: "Save Edits"});
        } else {
            this.setState({text: "Edit Menu"});
        }
    }

    render() {
        const { text } = this.state;

        return (
            <Button onClick={ () => { this.changeText()} } style={{ backgroundColor: text === "Save Edits" ? "#b9edee" : "#222222", color: text === "Save Edits" ? "#000000" : "#ffffff", border: text === "Save Edits" ? "none" : "1px solid #222222"}}>{text}</Button>
        );
    }
}

export default (EditMenuButton);

У меня есть EditMenuButton компонент, который имеет состояние со свойством text, и компонент MenuPage, который имеет состояние со свойством menuEditable.

Когда свойство text в компоненте EditMenuButton имеет значение 'Save Edits', Я хочу, чтобы свойство menuEditable в компоненте MenuPage имело значение true.

У меня есть данные, внешние по отношению к компонентам в моем приложении, которые составляют хранилище Redux (например, с использованием createStore() функция). Однако я не уверен, как изменить значение свойства состояния, когда состояние находится внутри компонента, как в случае компонентов MenuPage и EditMenuButton. Любые идеи приветствуются.

Ответы [ 2 ]

0 голосов
/ 14 апреля 2020

Создайте функцию для обновления состояния в родительском компоненте и передачи ее дочернему компоненту. В вашем родительском компоненте объявите:

toggleMenuEditable = () => {
  this.setState({ menuEditable: !this.state.menuEditable });
}

Передайте его дочернему компоненту как реквизит и вызовите его в функции changeText.

Примерно так:

changeText = () => {
    const { text } = this.state;
    if(text === "Edit Menu") {
        this.setState({text: "Save Edits"});
        this.props.toggleMenuEditable();

    } else {
        this.setState({text: "Edit Menu"});
    }
}
0 голосов
/ 14 апреля 2020

Обычно в React лучше всего хранить состояние у родителей и передавать его детям через реквизит, сосредоточив внимание на единственном источнике правды для состояния вашего приложения.

Рассмотрим только с menuEditable в вашем MenuPage и передачей этого в MenuButton через реквизит:

class MenuPage extends Component {

    state = {
        menuEditable: false
    }

    toggleMenuEditable = () => {
        this.setState((state) => ({
            menuEditable: !state.menuEditable;
        }));
    }

    render() {

        return (
            <div className='menu-page'>
                {this.props.menu ? this.props.menu.map(category => <MenuCategory key={category._id} {...category} />) : null}
                <div className='edit-menu-buttons'>
                    <div className='menu-button'>
                        {this.props.currentUser ? <NewCategoryButton /> : null}
                    </div>
                    <div className='menu-button'>
                        {this.props.currentUser ? <EditMenuButton onClick={this.toggleMenuEditable} isEditing={this.state.menuEditable} /> : null}
                    </div>
                </div>
            </div>
        )
    }
}

Ваша EditMenuButton теперь может быть значительно проще. Вам нужно будет сделать два изменения: удалить состояние и вместо этого использовать опору isEditing и передать опору onClick кнопке HTML

class EditMenuButton extends Component {
    render() {
        const { isEditing, onClick } = this.props;

        return (
            <Button onClick={onClick} style={{ backgroundColor: isEditing ? "#b9edee" : "#222222", color: isEditing ? "#000000" : "#ffffff", border: isEditing ? "none" : "1px solid #222222"}}>{isEditing ? "Save Edits" : "Edit Menu" }</Button>
        );
    }
}

Ваш EditMenuButton теперь не нужно заботиться об управлении состоянием, оно просто реагирует на входящие в него реквизиты, что облегчит работу (меньше думать) и будет менее подвержено ошибкам. Вы можете даже упростить это, сделав его функциональным компонентом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...