简体   繁体   English

如何将 state 从一个组件传递到另一个组件,如何修改 state?

[英]How can I pass the state from one component to another and how can I modify the state?

So I have所以我有

one component called section.js:一个名为 section.js 的组件:

import React from 'react';

import SectTitle from './Section_Title/Section_Title.js'
import SectContent from './Section_Content/Section_Content.js'

import classes from './Section.module.css'

const section = (props) => {
    const sectionNameMapping = {
        profile: 'Profile',
        education: 'Education',
        relevantWorkExp: 'Relevant Work Experience',
        otherWorkExp: 'Other Work Experience'
    }

    return (
        <div className={classes.Section}>
            <SectTitle title={sectionNameMapping[props.sectionName]} />
            <SectContent sectionName={props.sectionName}/>
        </div>
    )
}

export default section;

SectionTitle.js SectionTitle.js

import React,{Component} from 'react';

import classes from './Section_Title.module.css'

import expandArrow from '../../../assets/png_files/expand_arrow.png'

class SectTitle extends Component {
    state = {
        arrowClicked: false
    }

    displaySectionContents = () => {
        console.log('[displaySectionContents] Executed ... ' + this.state.arrowClicked)
        this.setState({
            arrowClicked: !this.state.arrowClicked
        })
    }

    render(){
    return (
        <div className={classes.SectionTitle}>
            <div>{this.props.title}</div>
            <div>
                <button
                 className={classes.ButtonSectTitle} 
                 onClick={this.displaySectionContents}>
                     <img className={classes.ExpandArrow} 
                      src={expandArrow} 
                      style={{transform: this.state.arrowClicked ? 'rotate(0deg)' : 'rotate(-90deg)'}}/></button></div>
           </div>
    )}
}

export default SectTitle;

SectionContent.js SectionContent.js

import React, { Component } from 'react';

import SectionItem from './Section_Item/Section_Item.js'

import classes from './Section_Content.module.css'

class SectionContent extends Component {   
    render() {
        return (
        <div className={classes.SectionContent}>
            <SectionItem sectionName={this.props.sectionName}/>
        </div>
        )
    }
}

export default SectionContent;

and SectionItem.js和 SectionItem.js

import React, { Component } from 'react';

import classes from './Section_Item.module.css';

import jsonContent from '../../../../assets/json_files/json_content.json';


class SectionItem extends Component {
    render() {
        if (Object.keys(jsonContent).includes(this.props.sectionName) && (this.props.sectionName == 'profile')) {
            return <div>{jsonContent[this.props.sectionName]}</div>
        } else {
            return <div>test</div>
        }
    }
}

export default SectionItem;

I need to set the state in the sectionTitle where my expand arrow is and the section content be displayed or not based on whether the button has been pressed or not.我需要在展开箭头所在的 sectionTitle 中设置 state,并根据按钮是否被按下来显示或不显示部分内容。

I am new to react and I don't know how o do this我是新手,我不知道该怎么做

for a simple tree like that you better move your arrowClicked and the handler to parent Section (turn it to a class based component).对于像这样的简单树,您最好将您的arrowClicked和处理程序移动到父Section (将其转换为基于 class 的组件)。 you then pass down as props displaySectionContents to SecTitle .然后,您将作为道具displaySectionContents传递给SecTitle since state is at parent tree you can conditional render Content based on arrowClicked state:由于 state 位于父树中,因此您可以根据arrowClicked state 有条件地渲染Content

class Section extends Component {

    state = {
        arrowClicked: false
    }

    displaySectionContents = () => {
        console.log('[displaySectionContents] Executed ... ' + this.state.arrowClicked)
        this.setState({
            arrowClicked: !this.state.arrowClicked
        })
    }

    return (
        <div className={classes.Section}>
            // pass down the arrow handler and arrowClicked
            <SectTitle title={sectionNameMapping[this.props.sectionName]} displaySectionContents={this.displaySectionContents} arrowClicked={this.props.arrowClicked}  />
             // if arrow clicked is true SectContent is rendered
            { this.state.arrowClicked && <SectContent sectionName={this.props.sectionName}/> } 
        </div>
    )
}

SectTitle becomes a function component since it doesnt need state, and you use only passed down props: SectTitle 成为 function 组件,因为它不需要 state,并且您只使用传递下来的道具:

const SectTitle = (props) {
    return (
        <div className={classes.SectionTitle}>
            <div>{props.title}</div>
            <div>
                <button
                 className={classes.ButtonSectTitle} 
                 onClick={props.displaySectionContents}>
                     <img className={classes.ExpandArrow} 
                      src={expandArrow} 
                      style={{transform: props.arrowClicked ? 'rotate(0deg)' : 'rotate(-90deg)'}}/></button></div>
           </div>
    )}
}

once you click on button props.displaySectionContents will update parent state, and SectionContent will have access to arrowClicked to be evaluated properly一旦你点击按钮props.displaySectionContents将更新父 state,并且SectionContent将有权访问arrowClicked以正确评估

There are many solutions.有很多解决方案。

The easiest one is to add some state to section component and getters/setters to children最简单的方法是添加一些 state 到section组件和 getter/setter 到孩子

const section = (props) => {
 const [arrowClicked, setArrowClicked] = useState(false)

 return (
        <div className={classes.Section}>
            <SectTitle displaySectionContents={() => setArrowClicked(true)} title={sectionNameMapping[props.sectionName]} />
            <SectContent arrowClicked={arrowClicked} sectionName={props.sectionName}/>
        </div>
    )

class SectTitle extends Component {
    state = {
        arrowClicked: false
    }

    return (
        <div className={classes.SectionTitle}>
            <div>{this.props.title}</div>
            <div>
                <button
                 className={classes.ButtonSectTitle} 
                 onClick={this.props.displaySectionContents}>
                     <img className={classes.ExpandArrow} 
                      src={expandArrow} 
                      style={{transform: this.state.arrowClicked ? 'rotate(0deg)' : 'rotate(-90deg)'}}/></button></div>
           </div>
    )}

class SectionContent extends Component {   
    render() {
        // this.props.arrowClicked
        return (
        <div className={classes.SectionContent}>
            <SectionItem sectionName={this.props.sectionName}/>
        </div>
        )
    }
}

Another one could be React.Context , use another state management framework like, Redux , MobX ... or just store state in window object, and trigger forceUpdate() , no don't do that Another one could be React.Context , use another state management framework like, Redux , MobX ... or just store state in window object, and trigger forceUpdate() , no don't do that

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

相关问题 如何从一个组件传递 state 以设置另一个 state? - How can I pass state from one component to set another state? React / Redux:如何将此状态从一个组件传递到另一个文件? - React/Redux: How can I pass this state from one component to another file? 如何在反应 class 组件中设置另一个 state 以将数据从初始 state 传递到 - How can I set another state to pass data to from the initial state in a react class component 如何更改另一个组件的状态? - How can I change the state of another component? 如何将状态从这个子组件传递给父组件? - How can I pass the state from this child to parent component? 如何将 state 从页面传递到组件并返回页面? - How can I pass state from page to component and back to page? 如何在 react 中重定向到另一个组件并传递我在前一个组件中设置的 state? - How can I redirect to another component in react and pass the state that I set in the previous component? 如何将值从一个组件传递到另一个组件? - How can I pass values from one component to another component? 如何将 state 从一条反应路线传递到另一条反应路线? - How can i pass a state from one react route to another react route? 我如何从 function 组件传递 state 以便我可以在 use-Context 中使用它 - How can I pass a state from a function component so i can use it in the use-Context
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM