如果子组件使用map()渲染,如何从子组件更改父组件的状态

时间:2018-11-04 10:19:57

标签: javascript reactjs

我有一个问题-我需要从子组件更改父组件的状态。我尝试使用道具使用标准变体,但对我的情况没有帮助。

这是父组件的代码:

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>
    )
  }
 }

2 个答案:

答案 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}
    )
 }