[英]The most “react” way to pass state to other components
I am fairly new to React. 我对React很陌生。 Currently I have two React components - Article.js and ControlForm.js
目前我有两个React组件-Article.js和ControlForm.js
My render return in Article.js is this: 我在Article.js中的渲染返回是这样的:
return (
<div className="article">
{article_wrapper.map( article =>
<div key={article.node.nid} className="article-main-display">
<h1 className="title" dangerouslySetInnerHTML={createMarkup(article.node.title)}/>
<div className="img-div"><img src={article.node.field_image.src} /></div>
<ControlForm />
<div dangerouslySetInnerHTML={createMarkup(article.node.field_user_hsk_level)} />;
<div className="field-name-field-chinese">
<div dangerouslySetInnerHTML={createMarkup(article.node.chinese)} />;
</div>
</div>
)}
</div>
);
The ControlForm.js has several form elements (all of which I'd like to be able to pass along if need be), but this is the main one: ControlForm.js具有多个表单元素(如果需要,我希望能够将其全部传递),但这是主要的元素:
<div className="form-item form-type-select form-group">
<label className="control-label">Font Size</label>
<select
value={this.state.value}
onChange={this.handleSizeSelect}
id="font-size"
className="form-control form-select"
>
<option value="0">Small</option>
<option value="1">Normal</option>
<option value="2">Large</option>
<option value="3">XL</option>
</select>
</div>
I'd like to be able to set a class on one of the divs in the Article.js based on changing a value in the ControlForm.js 我希望能够基于更改ControlForm.js中的值在Article.js中的一个div上设置一个类。
What is the most "React" way to do this? 最“反应”的方式是什么? Would creating a common parent to both be the best method (right now, their only parent in common is the main App.js)
最好同时创建一个共同的父母(目前,他们唯一的共同父母是主要的App.js)。
Sorry if I don't totally understand how this is supposed to work - this is my first React app. 抱歉,如果我不完全了解它应该如何工作,这是我的第一个React应用程序。
The class associated with the components are ControlForm and withFetching respectively. 与组件关联的类分别是ControlForm和withFetching。
EDIT - the demo example below works, but I have some additional issues with how to integrate it properly into my existing code. 编辑-下面的演示示例可以工作,但是在如何将其正确集成到现有代码中时,我还有一些其他问题。 Here's the existing functions of ControlForm:
这是ControlForm的现有功能:
class ControlForm extends Component {
constructor() {
super();
this.state = { toggleActive: false, sizeSelect: "0", speed: 1.3, volume: .6};
this.onToggle = this.onToggle.bind(this);
this.handleSpeedChange = this.handleSpeedChange.bind(this);
this.handleVolumeChange = this.handleVolumeChange.bind(this);
this.handleSizeSelect = this.handleSizeSelect.bind(this);
}
onToggle() {
this.setState({ toggleActive: !this.state.toggleActive });
}
handleSizeSelect(event) {
this.setState({ sizeSelect: event.target.value });
this.setState({font: 'large-font'});
parentMethod(event.target.value);
}
handlePlayClick(e) {
e.preventDefault();
voice.playButtonClick();
}
handlePauseClick(e) {
e.preventDefault();
voice.pauseButtonClick();
}
handleStopClick(e) {
e.preventDefault();
voice.stopButtonClick();
}
handleVolumeChange(event) {
console.log(event.target.value);
this.setState({ volume: event.target.value });
}
handleSpeedChange(event) {
console.log(event.target.value);
this.setState({ speed: event.target.value });
}
Articles looks like this: 文章如下所示:
const withFetching = (url) => (Comp) =>
class WithFetching extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: false,
error: null,
dynamicClassName: "parentClass"
};
this.changeClassName = this.changeClassName.bind(this);
}
changeClassName(childData) {
this.setState({
dynamicClassName: childData
});
}
componentDidMount() {
this.setState({ isLoading: true });
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Something went wrong ...');
}
})
.then(data => this.setState({ data, isLoading: false }))
.catch(error => this.setState({ error, isLoading: false }));
}
render() {
//return "test";
return <Comp { ...this.props } { ...this.state } />
}
}
function createMarkup(html) {
return {__html: html};
}
function changeClassName(childData) {
console.log("GETS HERE!")
this.setState({
dynamicClassName: childData
});
}
const Articles = ({ data, isLoading, error }) => {
console.log(data);
console.log(isLoading);
const article_wrapper = data.nodes || [];
if (error) {
return <p>{error.message}</p>;
}
if (isLoading) {
return <p>Loading ...</p>;
}
return (
<div className="article">
{article_wrapper.map( article =>
<div key={article.node.nid} className="article-main-display">
<h1 className="title" dangerouslySetInnerHTML={createMarkup(article.node.title)}/>
<div className="img-div"><img src={article.node.field_image.src} /></div>
<ControlForm parentMethod={changeClassName} />
<div dangerouslySetInnerHTML={createMarkup(article.node.field_user_hsk_level)} />;
<div className="field-name-field-chinese">
<div dangerouslySetInnerHTML={createMarkup(article.node.chinese)} />;
</div>
</div>
)}
</div>
);
}
export default withFetching(API)(Articles);
Sorry about all of these questions, I know a lot of this is due to unfamiliarity with React - this is the first thing I've tried to build in React 抱歉,所有这些问题,我知道很多原因是由于不熟悉React-这是我尝试在React中构建的第一件事
You want to change parents from his childs. 你想改变父母从他的孩子。
First, you have to create a handler function at Article.js and pass it to ControlForm.js as a property. 首先,您必须在Article.js中创建一个处理函数,并将其作为属性传递给ControlForm.js。
<ControlForm changeDiv={this.changeDiv} />
Then you focus on ControlForm.js, whenever you want to happen, you just execute the function you passed as a the prop changeDiv, like this.props.changeDiv()
然后,您将重点放在ControlForm.js上,只要您想发生,就只需执行作为prop changeDiv传递的函数,例如
this.props.changeDiv()
See also possible duplicate: How to update parent's state in React? 另请参见可能的重复项: 如何在React中更新父级的状态?
Article.js , Article.js,
class Article extends React.Component { constructor(props) { super(props); this.state = { dynamicClassName: "parentClass" } this.changeClassName = this.changeClassName.bind(this); } changeClassName(childData) { this.setState({ dynamicClassName: childData }); } // user dynamicClassName wherever u want . return ( < div className = "article" > { article_wrapper.map(article => < div key = { article.node.nid } className = "article-main-display" > < h1 className = "title" dangerouslySetInnerHTML = { createMarkup(article.node.title) } /> < div className = "img-div" > < img src = { article.node.field_image.src } /></div > < ControlForm parentMethod={this.changeClassName} / > < div dangerouslySetInnerHTML = { createMarkup(article.node.field_user_hsk_level) } />; < div className = "field-name-field-chinese" > < div dangerouslySetInnerHTML = { createMarkup(article.node.chinese) } />; < / div > < /div> ) } < /div> ); }
In ControlForm js , 在ControlForm js中,
class ControlForm extends React.Component { constructor(props) { super(props); this.state = { } this.handleSizeSelect= this.handleSizeSelect.bind(this); } handleSizeSelect() { this.props.parentMethod(this.state.value); } render() { return ( <div className="form-item form-type-select form-group"> <label className="control-label">Font Size</label> <select value={this.state.value} onChange={this.handleSizeSelect} id="font-size" className="form-control form-select" > <option value="0">Small</option> <option value="1">Normal</option> <option value="2">Large</option> <option value="3">XL</option> </select> </div> ); } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.