简体   繁体   中英

Bind value of property to value from another component

I am currently working on a learning project to get myself familiar with React. The app is a quiz-app and the end goal is for the user to get a sport recommendation based on the answers he gives. There are 8 questions, each one of them is representative of an attribute. On the app, below each question there is a slider which the user can change between 1 and 5 as the answer to the question.

I would like to have something similar to an athlete's profile below the questions and that would be a bar-chart, with each column being an attribute and the value of the column being equal to the answer.

This is my component that displays the question with the slider:

import React, { Component } from 'react';
import { Slider } from '@material-ui/core';
import './FirstComponent.css';
import { IoIosArrowBack } from "react-icons/io";
import { IoIosArrowForward } from "react-icons/io";
export default class FirstComponent extends Component {

    constructor(props) {
        super(props);
        this.state = {
            textValue: "Select your answer",
            answerValue: 3,
        };
        this.maxValue = 5;
        this.minValue = 1;
    }

    changeTextBasedOnSliderValue = (value) => {
        let intValue = parseInt(value);
        const answersArray = this.props.answers;
        this.setState({
            textValue: answersArray[intValue - 1],
            answerValue: value,
        })
    }

    updateSliderValue = (increase) => {
        if (increase && this.state.answerValue < this.maxValue) {
            this.setState(prevState => ({
                answerValue: prevState.answerValue + 1,
                textValue: this.props.answers[this.state.answerValue] // an
            }))
        }
        else if (!increase && this.state.answerValue > this.minValue) {
            this.setState(prevState => ({
                answerValue: prevState.answerValue - 1,
                textValue: this.props.answers[this.state.answerValue - 2]
            }))
        }
    }



    render() {
        return (
            <div className="sliderQuestion">
                <h2 className="questionText">{this.props.index}. {this.props.question}</h2>
                <h4 className="answer">{this.state.answerValue}</h4>
                <p className="answer">{this.state.textValue}</p>
                <IoIosArrowBack onClick={(e) => this.updateSliderValue(false)} className="left-icon" />
                <IoIosArrowForward onClick={(e) => this.updateSliderValue(true)} className="right-icon" />
                <Slider
                    defaultValue={3}
                    min={this.minValue}
                    max={this.maxValue}
                    value={this.state.answerValue}
                    valueLabelDisplay="off"
                    onChange={(e, value) => this.changeTextBasedOnSliderValue(value)}
                />

            </div>
        )
    }
}

And this is my App,js code

import React, { Component } from 'react';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css'
import 'react-bootstrap-range-slider/dist/react-bootstrap-range-slider.css';
import FirstComponent from './FirstComponent';
import Button from 'react-bootstrap/Button';
import BarChart from 'react-bar-chart';


class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      questions: [],
      barChartData: [],
    };
    this.barChartData = []
  }

  async componentDidMount() {
    const url = "http://localhost:9000/connection";
    const response = await fetch(url);
    const data = await response.json();
    for (var i = 0; i < data.length; i++) {
      let barChartColumn = {
        text : data[i].Attribute,
        value : 10,
      }
      this.barChartData.push(barChartColumn);
      var item = <FirstComponent key={data[i]._id} index={i + 1} question={data[i].Question} answers={data[i].Answers} />
      this.setState({
        questions: [this.state.questions, item],
        barChartData: this.barChartData,
      })
    };
  }

  render() {
    return (
      <div className="container">
        <h2 className="header-title">Which sport are you made for?</h2>
        {this.state.questions}
        <Button className="results-button" variant="primary">Get my results</Button>
        <BarChart ylabel=''
          data={this.state.barChartData}
          width={900}
          height={500}
          margin={{ top: 20, right: 70, bottom: 30, left: 70 }} />
      </div>
    );
  }
}


export default App;

My question is how could I bind the value of a barChartColumn to the answerValue of a slider component and have it update when the value changes?

Don't waste your time. Even if you share values between component (classes) as you would like to, you'll be in problem when values in one of the components get changed. Other component won't be aware if the change.

Use state and props instead

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM