Реагировать на проблему общения от ребенка к родителю - PullRequest
0 голосов
/ 22 декабря 2018

Я строю игру на угадывание, в которой вопросы и логика выбора находятся в компоненте «Вопросы».У меня проблемы с получением приложения для чтения кода Вопросы.Я хочу, чтобы состояние в App обновлялось на основе выборок в дочернем компоненте.

Я пытался выполнить обратное проектирование решения из Как передать данные из дочернего компонента его родительскому компоненту в ReactJS? и https://malithjayaweera.com/2018/01/reactjs-passing-data-react-components/,, но я не знаю, как применить его к моему проекту.

Приложение:

import React, { Component } from 'react';
import './App.css';
import Timer from "./Timer";
import Questions from "./Questions/Questions.js";
import Results from "../src/Results";

class App extends Component {

  state = {
    totalTrue: 0,
    totalFalse: 0,
  }

  componentDidMount() {
    console.log(`TotalTrue: ${this.state.totalTrue}`);
    console.log(`TotalFalse: ${this.state.totalFalse}`);
  }

  // submit button
  handleFormSubmit = event => {
    event.preventDefault();
    console.log("submit button clicked");
  };

  callbackHandlerFunction = (selectedOption) => {
    this.setState({ selectedOption });
  }

  render() {
    return (

      <div className="parallax">

      <div className="App">

      <div className="wrapper">

      <div className="headerDiv">
      <h1>Pixar Trivia!</h1>
    </div>

    <div className="timerDiv">
      <Timer />
      </div>

      <div className="questionSection">
      <Questions
    handleClickInParent={this.callbackHandlerFunction}
    />
    </div>

    <div>
    <button onClick={this.handleFormSubmit}>Submit</button>
      </div>

    {/* this.state.articles.length > 0 && ...*/}
  <div className="resultsDiv">
      <Results
    totalTrue={this.state.totalTrue}
    totalFalse={this.state.totalFalse}
    />
    </div>

    </div>

    </div>

    </div>
  );
  }
}

export default App;

Вопросы:

import React, { Component } from "react";
import Select from "react-select";
import "./Questions.css";

const answerChoices = [
    {
        id: 1,
        text: "1. The background image is the carpet from Sid's house in Toy Story. What movie inspired it?",
        answers: [
        {
            label: "2001: A Space Odyssey",
            value: false
        },
        {
            label: "The Shining",
            value: true
        },
        {
            label: "One Flew Over the Cuckoo's Nest",
            value: false
        },
        {
            label: "The Godfather",
            value: false
        }
        ]
},
  ---- full questions cut for space. I'm using https://github.com/JedWatson/react-select and the functionality works. ----
{
    id: 8,
    text: "8. Who was the original voice of Marlin from “Finding Nemo”?",
    answers: [
        {
            label: "Albert Brooks",
            value: false
        },
        { 
            label: "Denis Leary",
            value: false
        },
        {
            label: "Brad Garrett",
            value: false
        },
        {
            label: "William H. Macy",
            value: true
        }
        ]
    }
];

class Questions extends Component {

state = {
    answerChoices,
    selectedOption: null,
}

handleChange = (selectedOption) => {
    this.setState({ selectedOption });
    console.log(`Option selected:`, selectedOption);

    const answerValue = selectedOption.value;
    if (answerValue === true) {
        // console.log(answerValue);
        this.setState({totalTrue: this.totalTrue + 1}, () => {
            console.log(`New TotalTrue: ${this.totalTrue}`);
        });
    };
    if (answerValue === false) {
        // console.log(answerValue);
        this.setState({totalFalse: this.totalFalse + 1}, () => {
            console.log(`New TotalFalse: ${this.totalFalse}`);
        });
    };
    this.props.handleClickInParent({selectedOption});

  }

render() {
    // const { selectedOption } = this.state;

    return (

        <div className="questionsDiv">

            <ol>
                {this.state.answerChoices.map(question => {
                return (

                    <div className="individualQuestions" key={question.id}>

                        {question.text}

                        <Select
                            value={this.selectedOption}
                            onChange={this.handleChange}
                            options={question.answers}
                        />

                    </div>

                    )  
                })}
            </ol>

        </div>

    )
  }

}

export default Questions;

Ответы [ 2 ]

0 голосов
/ 23 декабря 2018

Я внес некоторые изменения, и теперь он работает.

Код выглядит следующим образом.

callbackHandlerFunction = ( selectedOption ) => {
  const answerValue = selectedOption.value;
  if (answerValue === true) {
      // console.log(answerValue);
      this.setState({totalTrue: this.state.totalTrue + 1}, () => {
          console.log(`New TotalTrue: ${this.state.totalTrue}`);
      });
  };
  if (answerValue === false) {
      // console.log(answerValue);
      this.setState({totalFalse: this.state.totalFalse + 1}, () => {
          console.log(`New TotalFalse: ${this.state.totalFalse}`);
      });
  };
}  

и

handleChange = (selectedOption) => {

    this.props.handleClickInParent(selectedOption);
  }
0 голосов
/ 22 декабря 2018

Посмотрите на эту строку в Question:

this.props.handleClickInParent({selectedOption});

Он передает { selectedOption } в callbackHandlerFunction в App.Теперь эта последняя функция в App принимает один аргумент selectedOption и продолжает обновлять состояние, используя ее.Все вместе вы обновляете состояние в App, используя:

this.setState({ { selectedOption } }); // this is wrong.

Чтобы исправить проблему, используйте this.props.handleClickInParent(selectedOption) (без фигурных скобок) вместо Question.

В качестве альтернативы, если вы игнорируете вышеприведенное , вы также можете исправить проблему, изменив подпись callbackHandlerFunction, чтобы она выглядела так:

callbackHandlerFunction = ({ selectedOption }) => { // note the curly braces.
    this.setState({ selectedOption });
}    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...