Как увеличить значение в одном компоненте родственного элемента от другого при клике? - PullRequest
0 голосов
/ 08 сентября 2018
function LeagueBadge(props) {
    return (
        <img src={props.badgeUrl} alt="missing alt text" />
    );
}

class LeagueInfo extends Component {
    constructor(props) {
        super(props);
        this.state = {
            amountOfPlayers: null,
            rpPerSecond: null,
            rpCost: null,
        };
    }
    render() {
        return (
            <div>
                <h4>{this.props.name} players: {this.props.amountOfPlayers}</h4>
                <h4>RP per second: {this.props.rpPerSecond}</h4>
                <h4>RP cost: {this.props.rpCost}</h4>
            </div>
        );
    }
}

class League extends Component {
    render() {
        return (
            <div>
                <LeagueBadge badgeUrl={this.props.badge} />
                <LeagueInfo name={this.props.name} />
            </div>
        );
    }
}

class App extends Component {
    render() {
        return (
            <div className="App">
                <h1>Players</h1>
                <League name="Bronze" badge={ require('./bronze.png') }></League>
                <League name="Silver" badge={ require('./silver.png') }></League>
                <League name="Gold" badge={ require('./gold.png') }></League>
                <League name="Platinum" badge={ require('./platinum.png') }></League>
                <League name="Diamond" badge={ require('./diamond.png') }></League>
                <League name="Master" badge={ require('./master.png') }></League>
                <League name="Challenger" badge={ require('./challenger.png') }></League>
            </div>
        );
    }
}

Я хочу иметь возможность щелкнуть по изображению, являющемуся компонентом LeagueBadge, и увеличить значение amountOfPlayers в их одноимённом LeagueInfo. Я уже гуглил реакцию на связь с братьями и сестрами и нашел только примеры с тегом input и onChange, но здесь я хочу тег img или button и onClick.

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

Сохраните свой штат в компоненте лиги и передайте функцию, ответственную за его изменение, в LeagueBadge, например:

class League extends Component {
    constructor(props) {
        super(props);
        this.state = {
            amountOfPlayers: null,
        };
    }
    handleClick = () => {
    this.setState(prevState => {
       return {amountOfPlayers: prevState.amountOfPlayers + 1}
    })
  }
    render() {
        return (
            <div>
                <LeagueBadge badgeUrl={this.props.badge} incrementPlayers={this.handleClick}/>
                <LeagueInfo name={this.props.name} amountOfPlayers={this.state.amountOfPlayers}/>
            </div>
        );
    }
}


function LeagueBadge(props) {
    return (
        <img src={props.badgeUrl} alt="missing alt text" onClick={this.props.incrementPlayers}/>
    );
}

используйте this.props.amountOfPlayers в компоненте Info.

0 голосов
/ 08 сентября 2018

Вы можете поднять состояние для amountOfPlayers в свой <Leauge /> компонент, чтобы: - обновления могут запускаться с <LeagueBadge /> - и это состояние может быть передано вашему <LeagueInfo /> компоненту

Это позволит вам совместно использовать и синхронизировать состояние между братьями и сестрами <LeagueInfo /> и <LeagueBadge /> по мере необходимости.

Чтобы сделать это, вам нужно добавить обратный вызов onClick к <LeagueBadge />, который срабатывает при нажатии на элемент img. В методе рендеринга <Leauge /> вы можете предоставить логику, которая увеличивает состояние amountOfPlayers в <Leauge />. Когда amountOfPlayers увеличивается и вызывается setState<Leauge />), это, в свою очередь, заставит ваш <Leauge /> компонент перерисовать себя (и потомков / братьев и сестер). Поскольку обновленное значение для amountOfPlayers передается в качестве опоры компоненту <LeagueInfo />, это обновленное значение будет отображаться в <LeagueInfo /> - эффективно достигая того, что вам нужно.

Что-то подобное может работать для вас:

class LeagueBadge extends Component {
    render() {

    // Add props.onClick callback to trigger click event in <League /> 
    // component
    return (
        <img src={this.props.badgeUrl} alt="missing alt text" 
             onClick={() => this.props.onClick()} />
    );
    }
}

class LeagueInfo extends Component {
    constructor(props) {
        super(props);
        this.state = {
            // amountOfPlayers: null, // This is not needed, as it's supplied by props
            rpPerSecond: null,
            rpCost: null,
        };
    }
    render() {
        return (
            <div>
                <h4>{this.props.name} players: {this.props.amountOfPlayers}</h4>
                <h4>RP per second: {this.props.rpPerSecond}</h4>
                <h4>RP cost: {this.props.rpCost}</h4>
            </div>
        );
    }
}

class League extends Component {

    componentWillMount() {

        this.setState({
            amountOfPlayers : 0
        })
    }

    render() {

        // Locally defined function that increments amountOfPlayers and
        // updates state
        const incrementAmountOfPlayers  = () => {
            this.setState({ amountOfPlayers : 
            this.state.amountOfPlayers + 1 })
        }

        return (
            <div>
                <LeagueBadge badgeUrl={this.props.badge} 
                             onClick={ () => incrementAmountOfPlayers() } />
                <LeagueInfo name={this.props.name} amountOfPlayers={ this.state.amountOfPlayers } />
            </div>
        );
    }
}
...