父组件中的复选框不会在React.js中的子组件中触发函数

时间:2018-06-12 22:08:16

标签: javascript reactjs

在我的父组件中,我有四个复选框,基本上我希望每个复选框显示(如果选中)或不显示(如果未选中)我在子组件中创建的函数的值。

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      weatherFromInput: null,
      dataTracker: null,
      isChecked: false,
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
  }

  componentDidMount() {
    console.dir(dataTracker);
  }

  handleChange(event) {
    this.setState({
      input: event.target.value,
    });
  }

  handleCheckboxChange(event) {
    console.log('checkbox changed!', event);
    this.setState({ isChecked: event.target.checked });
  }

  handleSubmit(event) {
    event.preventDefault();
    var mode = function mode(arr) {
      return arr.reduce(
        function(current, item) {
          var val = (current.numMapping[item] = (current.numMapping[item] || 0) + 1);
          if (val > current.greatestFreq) {
            current.greatestFreq = val;
            current.mode = item;
          }
          return current;
        },
        { mode: null, greatestFreq: -Infinity, numMapping: {} },
        arr
      ).mode;
    };
    var promises = Promise.all([api.getWeather(this.state.input), api.getForecast(this.state.input)]);

    promises.then(
      function(input) {
        var firstSevenDays = input[1].list.slice(0, 7);
        var tempertures = firstSevenDays.map(function(day) {
          return Math.floor(day.main.temp);
        });
        var dataObj = new dataTracker(
          input[0].main.temp_min,
          input[0].main.temp_max,
          input[0].main.temp_min + input[0].main.temp_max / 2,
          mode(tempertures)
        );
        this.setState({ weatherFromInput: input[0], input: '', dataTracker: dataObj });
      }.bind(this)
    );
  }

  render() {
    return (
      <div className="container">
        <div className="container">
          <form name="weatherApp" onSubmit={this.handleSubmit}>
            <h2>Open Weather App</h2>
            <div className="row">
              <div className="one-half column">
                <label htmlFor="insertMode">Insert your location</label>
                <input
                  name="zipcode"
                  className="u-full-width"
                  placeholder="please enter city or zipcode"
                  type="text"
                  autoComplete="off"
                  value={this.state.input}
                  onChange={this.handleChange}
                />
              </div>
              <div className="one-half column">
                <label htmlFor="showMin">show minimum</label>
                <input type="checkbox" onChange={this.handleCheckboxChange} checked={this.state.isChecked} />
                <label htmlFor="showMax">show maximum</label>
                <input type="checkbox" onChange={this.handleCheckboxChange} checked={this.state.isChecked} />
                <label htmlFor="showMean">show mean</label>
                <input type="checkbox" onChange={this.handleCheckboxChange} checked={this.state.isChecked} />
                <label htmlFor="showMean">show mode</label>
                <input type="checkbox" onChange={this.handleCheckboxChange} checked={this.state.isChecked} />
              </div>
            </div>
            <div className="row">
              <div className="two-half column">
                <input type="submit" value="Submit" />
              </div>
            </div>
          </form>
        </div>

        <div className="container">
          <div className="row">
            <div className="twelve columns">
              {this.state.weatherFromInput !== null ? (
                <WeatherDisplay dataTracker={this.state.dataTracker} weather={this.state.weatherFromInput} />
              ) : null}
            </div>
          </div>
        </div>
      </div>
    );
  }
}

这是我的孩子组成部分:

export default function WeatherDisplay(props) {
  var { weather, dataTracker } = props;
  console.log('dataTracker', dataTracker);

  return (
    <div className="weather-display">
      <h1>{weather.name}</h1>
      <h2>{`Current temperature: ${Math.floor(weather.main.temp)}`}</h2>
      <h3>{`Current humidity: ${weather.main.humidity}%`}</h3>
      <h4>{`Minimum temperature: ${dataTracker.showMin()}%`}</h4>
      <h4>{`Maximum temperature: ${dataTracker.showMax()}%`}</h4>
      <h4>{`Mean temperature: ${dataTracker.showMean()}%`}</h4>
      <h4>{`Mode temperature: ${dataTracker.showMode()}%`}</h4>

    </div>
  );
}

如何将它们连接在一起?

1 个答案:

答案 0 :(得分:1)

为了实现您的目标,您必须执行以下操作:

  1. 为每个复选框添加标识符(id属性,名称属性)
  2. 将您的isChecked州更改为checkedItems阵列
  3. 将onChange逻辑更改为
  4. handleCheckboxChange(event) {
    
      const target = event.target;
      const id = target.id; // Or target.getAttribute('name');
      const isChecked = target.checked;
      const { checkedItems } = this.state;
    
      // Item was unchecked
      if (!isChecked) {
        // Remove it from the list
        const updatedItems = checkedItems.filter(item => item !== id);
        // Update state
        this.setState({ checkedItems: updatedItems });
        // Break
        return;
      }
    
      // Add the new item
      const updatedItems = checkedItems.concat(id);
      // Update state
      this.setState({ checkedItems: updatedItems });
      
    }

    1. 发送作为WeatherDisplay组件的道具:
    2. <WeatherDisplay dataTracker={this.state.dataTracker} weather={this.state.weatherFromInput} checkedItems={this.state.checkedItems} />

      1. 访问checkedItems组件
      2. 中的WeatherDisplay道具

        我编写了更新的handleCheckboxChange方法,但未对其进行测试,因此可能需要进行一些调整,但基本上这是如何做的。