我编写了一个状态为chosenGenre
的组件,在其中,有一个函数可以根据所单击的按钮更改状态。
我想获取更新后的状态(即string
)并在其他组件中使用它。
这是声明状态的组件:
import React, { Component } from 'react';
import Genre from './Genre';
import './GenreSelectPage.css';
import Blues from '../Blues.png';
import Classical from '../Classical.png';
import Country from '../Country.png';
export default class GenreSelectPage extends Component{
state = {
chosenGenre: ""
}
handleClick = (genreName) => {
this.setState({ chosenGenre: genreName });
}
render() {
return(
<div className = "GenreSelectPage">
<h3>Select your desired Kollab Room Genre</h3>
<Genre genrePicture= {Blues} genreClicked = {()=>this.handleClick("Blues")}/>
<Genre genrePicture= {Classical} genreClicked = {()=>this.handleClick("Classical")}/>
<Genre genrePicture= {Country} genreClicked = {()=>this.handleClick("Country")}/>
</div>
)
}
}
这是我想使用chosenGenre
组件中的GenreSelectPage
状态的新组件:
import React, { Component } from 'react';
import GenreSelectPage from './GenreSelectPage';
export default class InRoomPage extends Component {
render() {
return(
<div className = "InRoomPage">
<p>Welcome to {GenreSelectPage.state.chosenGenre} page</p>
</div>
)
}
}
我应该在以下内容中进行哪些更改:
<p>Welcome to {GenreSelectPage.state.chosenGenre} room !</p>
那么它将起作用吗?
答案 0 :(得分:2)
共同的父母:(您可以将状态提高一级)
如果这些组件具有一个公共父组件,那么您需要将此状态向上移动到公共父组件中,并传递处理程序以将状态更新为GenreSelectPage
并传递状态为props
进入InRoomPage
。
没有共同的父母 :(可以使用Redux)
您需要使用 Redux ,在那里您声明将保留在一个中央存储中,并且可以从组件树的任何部分从任何组件连接到该存储。并将状态变成道具。
用法:https://redux.js.org/basics/usage-with-react
将组件移到同一父对象下:
您可以创建一个名为 componentParent 的新组件(根据您的应用使用名称),将状态存储在该组件中。
import React, { Component } from 'react';
import GenreSelectPage from './GenreSelectPage';
import InRoomPage from './InRoomPage';
export default class componentParent extends Component {
state = {
chosenGenre: ""
}
handleClick = (genreName) => {
this.setState({ chosenGenre: genreName });
}
render() {
return(
<div className = "InRoomPage">
<GenreSelectPage clickHandler={this.handleClick}></GenreSelectPage>
<InRoomPage chosenGenre={this.state.chosenGenre}></InRoomPage>
</div>
)
}
}
也请检查Context API
答案 1 :(得分:0)
您可以尝试以下任何操作
a。将状态移至GenreSelectPage
和InRoomPage
的公共父组件。将handleGenereChange
方法传递给GenreSelectPage
作为道具,并在parentComponent
中设置状态。将状态值作为道具发送到InRoomPage
。这称为提升状态。有关更多详细信息,请访问https://reactjs.org/docs/lifting-state-up.html
b。使用Redux。有关https://almerosteyn.com/2016/08/redux-explained-again
的更多信息答案 2 :(得分:0)
正如其他人所提到的,在组件之间共享状态的常见方法是使用Redux,MobX是另一种选择。
这是Redux应用程序的基本示例。有两个组件,一个组件将值写入Redux存储,另一个组件从Redux存储读取值。
设置Redux的关键部分是:
<Provider>
-包装您的整个应用并为商店提供商品,也称为简化器connect
-此函数将您的组件连接到redux,其前两个参数为mapStateToProps
和mapDispatchToProps
mapStateToProps
-此参数是允许您从状态(redux存储)中读取的函数,它将把值放入this.props
mapDispatchToProps
-从此处完成更新商店的调度动作减速器,动作和选择器通常位于单独的文件中,因此可以轻松地在组件之间共享它们。
下面的组件也将放在单独的文件中,并且您将export default
的{{1}}部分。
connect
const { Component } = React;
const { applyMiddleware, createStore } = Redux;
const { connect, Provider } = ReactRedux;
/*********************/
/** GenreSelectPage **/
/*********************/
class GenreSelectPage extends Component {
constructor(props) {
super(props);
this.selectGenre = this.selectGenre.bind(this);
}
selectGenre(e) {
const genre = e.target.value;
this.props.selectGenre(genre);
}
render() {
return (
<div>
<h3>GenreSelectPage Component</h3>
<select onChange={this.selectGenre}>
<option value="">Select a genre</option>
<option value="blues">Blues</option>
<option value="classical">Classical</option>
<option value="country">Country</option>
</select>
</div>
)
}
}
// Write to store
const mapDispatchToProps = (dispatch) => ({ selectGenre: (genre) => dispatch({type: 'SELECT_GENRE', genre}) })
// Connect to store
const GenreSelectComponent = connect(null, mapDispatchToProps)(GenreSelectPage);
/*******************/
/** InRoomPage **/
/*******************/
class InRoomPage extends Component {
render() {
return (
<div>
<h3>InRoomPage Component</h3>
<p>{this.props.genre}</p>
</div>
)
}
}
// Read from store
const mapStateToProps = (state) => ({ genre: state.genre });
// Connect to store
const InRoomComponent = connect(mapStateToProps)(InRoomPage);
/*******************/
/** REDUX **/
/*******************/
const INITIAL_STATE = {
genre: null
}
const reducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case 'SELECT_GENRE':
return {
...state,
genre: action.genre
}
default:
return state;
}
};
const store = createStore(reducer);
// Provider (from Redux) wraps around your entire app
ReactDOM.render(
<Provider store={store}>
<GenreSelectComponent />
<InRoomComponent />
</Provider>,
document.getElementById('root')
);