我有一个问题-我需要从子组件更改父组件的状态。我尝试使用道具使用标准变体,但对我的情况没有帮助。
这是父组件的代码:
class ThemesBlock extends React.Component {
constructor(props){
super(props);
this.state = {
currentThemeId: 0
}
}
changeState(n){
this.setState({currentThemeId: n})
}
render() {
let { data } = this.props;
return (
data.map(function (item) {
return <Theme key={item.id} data={item} changeState=
{item.changeState}/>
})
)
}
}
这是我的子组件代码:
class Theme extends React.Component {
constructor(props){
super(props);
this.changeState = this.props.changeState.bind(this);
}
render() {
const { id, themename } = this.props.data;
const link = '#themespeakers' + id;
return (
<li><a href={link} onClick={() => this.changeState(id)}
className="theme">{themename}</a></li>
)
}
}
答案 0 :(得分:1)
主要问题是changeState
应该绑定到ThemesBlock
实例,而不是{{1}实例(由Theme
)绑定。
在下面的示例中,我将其绑定到ThemesBlock
构造函数中(我还对其进行了更新,以显示所选的主题ID):
ThemesBlock
class ThemesBlock extends React.Component {
constructor(props) {
super(props);
this.state = {
currentThemeId: 0
}
this.changeState = this.changeState.bind(this);
}
changeState(n) {
this.setState({currentThemeId: n})
}
render() {
let { data } = this.props;
return (
<div>
<div>
Current theme ID: {this.state.currentThemeId}
</div>
{data.map(item => {
return <Theme key={item.id} data={item} changeState={this.changeState} />
})}
</div>
)
}
}
class Theme extends React.Component {
constructor(props) {
super(props);
this.changeState = this.props.changeState.bind(this);
}
render() {
const {
data: {
id,
themename
},
changeState
} = this.props;
const link = '#themespeakers' + id;
return (
<li><a href={link} onClick={() => changeState(id)} className="theme">{themename}</a></li>
)
}
}
const data = [
{id: 1, themename: "One"},
{id: 2, themename: "Two"},
{id: 3, themename: "Three"}
];
ReactDOM.render(
<ThemesBlock data={data} />,
document.getElementById("root")
);
答案 1 :(得分:-2)
您是否尝试过在返回前移动map()?像这样:
render() {
let { data } = this.props;
const outputTheme = data.map(function (item) {
return <Theme key={item.id} data={item} changeState= {item.changeState}/>
})
return (
{outputTheme}
)
}