[英]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.