尝试在其他组件单击功能中渲染组件时为什么不反应组件渲染

时间:2018-07-06 09:17:06

标签: javascript reactjs

我正在尝试将按钮呈现到页面上,单击该按钮后,将根据单击的日期将硬编码的天气数据呈现到页面上。 click函数可以正常工作,并且按我期望的方式呈现按钮,但是单击按钮Day时不会呈现。

由于我的代码到达了点击处理程序函数中的console.log,因此我不知道自己在做什么。然后,处理程序函数应呈现组件,但由于某些原因,它不呈现。

这是我的代码:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import myData from "./weather.json";

class Day extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      description: null
    };
  }

  render() {
    console.log("at last"); //this isn't reached
    return (
      <div className="dayWeather">
        <div className="dayWeather">Humidity {this.props.humidity}</div>
        <div className="dayWeather">Temperature {this.props.temperature}</div>
      </div>
    );
  }
}

class DayRow extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      days: Array(7).fill(null)
    };
    this.handler = this.handler.bind(this);
    this.renderDay = this.renderDay.bind(this);
  }

  handler(day) {
    let daysWeather = myData[day];
    console.log("now we've reached this far"); //this console log is reached when a button is clicked.
    return (
      <Day
        humidity={daysWeather.humidity}
        temperature={daysWeather.temperature}
      />
    );
  }

  renderDay(day) {
    return (
      <div>
        <button
          className="day"
          onClick={() => {
            this.handler(day);
          }}
        >
          {day}
        </button>
      </div>
    );
  }

  render() {
    return (
      <div>
        <div className="day-row">
          {this.renderDay("Monday")}
          {this.renderDay("Tuesday")}
          {this.renderDay("Wednesday")}
          {this.renderDay("Thursday")}
          {this.renderDay("Friday")}
          {this.renderDay("Saturday")}
          {this.renderDay("Sunday")}
        </div>
      </div>
    );
  }
}

class Weather extends React.Component {
  render() {
    return (
      <div className="weather">
        <div className="weather-panel">
          <DayRow />
        </div>
        <div className="day" />
      </div>
    );
  }
}
// ========================================

ReactDOM.render(<Weather />, document.getElementById("root"));

4 个答案:

答案 0 :(得分:0)

请勿在点击处理程序中返回UI元素,因为它不会呈现。只需在处理程序中设置一个标志,并使用它在渲染函数中显示Day组件即可。

class DayRow extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
    days: Array(7).fill(null),
    showDay: false
  };
  this.handler = this.handler.bind(this);
  this.renderDay = this.renderDay.bind(this);
}

handler() {
  this.setState({
    showDay: true,
  });
}

renderDayComponent(day) {
  let daysWeather = myData[day];
  console.log("now we've reached this far"); //this console log is reached when a button is clicked.
  return (
    <Day
      humidity={daysWeather.humidity}
      temperature={daysWeather.temperature}
    />
  );
}

renderDay(day) {
  return (
    <div>
      <button
        className="day"
        onClick={() => {
          this.handler();
        }}
      >
        {day}
      </button>
      {this.state.showDay && this.renderDayComponent(day)}
    </div>
  );
}

render() {
  return (
    <div>
      <div className="day-row">
        {this.renderDay("Monday")}
        {this.renderDay("Tuesday")}
        {this.renderDay("Wednesday")}
        {this.renderDay("Thursday")}
        {this.renderDay("Friday")}
        {this.renderDay("Saturday")}
        {this.renderDay("Sunday")}
      </div>
    </div>
  );
}
}

答案 1 :(得分:0)

我的猜测是您要在Weather作曲中渲染这一天吗?为此,您必须保留某种state,以便React知道要渲染什么。每当您更改状态时,React都会调用render重新呈现您的礼物。

因此,由于要显示的一天状态是天气组件的本地状态,因此您需要将状态存储在此处:

class Weather extends React.Component {
  constructor(props) { 
    super(props)
    this.state = { activeDay: undefined }
  }

  render() {
    // Store the current dayData in a variable if an activeDay is chosen, it will be falsy if no day has been chosen.
    const dayData = this.state.activeDay && myData[this.state.activeDay]
    return (
      <div className="weather">
        <div className="weather-panel">
          // DayRow will inform Weather when a day has been selected, i.e., clicked
          <DayRow onSelected={day => this.setState({ activeDay: day })} />
        </div>
        <div className="day">
          // This is where you are rendering the day, only if a day
          // is active. I.e., dayData is truthy
          { dayData && <Day humitidy={dayData.humitidy} temperature={dayData.temperature} /> }
        </div>
      </div>
    );
  }
}

您的DayRow可以通过说出选择了哪一天来简单地与Weather进行交流。

class DayRow extends React.Component {
  constructor(props) {
    super(props);
    this.renderDay = this.renderDay.bind(this)
  }

  renderDay(day) {
    return (
      <div>
        <button
          className="day"
          onClick={() => {
            this.props.onSelected(day);
          }}
        >
          {day}
        </button>
      </div>
    );
  }

  render() {
    return (
      <div>
        <div className="day-row">
          {this.renderDay("Monday")}
          {this.renderDay("Tuesday")}
          {this.renderDay("Wednesday")}
          {this.renderDay("Thursday")}
          {this.renderDay("Friday")}
          {this.renderDay("Saturday")}
          {this.renderDay("Sunday")}
        </div>
      </div>
    );
  }
}

答案 2 :(得分:0)

从事件处理程序中返回JSX不会呈现它。您必须使用组件的render方法进行所有渲染。

您可以在state中添加一个附加对象,以跟踪是否单击了day,并在渲染中使用该state

class DayRow extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      days: Array(7).fill(null),
      showDays: {}
    };
    this.handler = this.handler.bind(this);
    this.renderDay = this.renderDay.bind(this);
  }

  handler(day) {
    this.setState(previousState => {
      const showDays = { ...previousState.showDays };
      showDays[day] = !showDays[day];
      return { showDays };
    });
  }

  renderDay(day) {
    let daysWeather = myData[day];
    return (
      <div>
        <button
          className="day"
          onClick={() => {
            this.handler(day);
          }}
        >
          {day}
        </button>
        {this.state.showDays[day] && (
          <Day
            humidity={daysWeather.humidity}
            temperature={daysWeather.temperature}
          />
        )}
      </div>
    );
  }

  // ...
}

答案 3 :(得分:0)

处理程序函数返回的组件将传递给onClick事件。它没有进入DOM树。

您可以如下所示更改代码。

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import myData from './weather.json';

const myData = 
class Day extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      description: null
    };
  }

  render() {
    console.log('at last'); //this isn't reached
    return (
      <div className="dayWeather">
        <div className="dayWeather">Humidity {this.props.humidity}</div>
        <div className="dayWeather">Temperature {this.props.temperature}</div>
      </div>
    );
  }
}

class DayRow extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      days: Array(7).fill(null)
    };
    this.handler = this.handler.bind(this);
    this.renderDay = this.renderDay.bind(this);
  }

  handler(day) {
    let daysWeather = myData[day];
    console.log('now we\'ve reached this far'); //this console log is reached when a button is clicked.
    this.props.handler(daysWeather);
  }

  renderDay(day) {
    return (
      <div>
        <button
          className="day"
          onClick={() => {
            this.handler(day);
          }}
        >
          {day}
        </button>
      </div>
    );
  }

  render() {
    return (
      <div>
        <div className="day-row">
          {this.renderDay('Monday')}
          {this.renderDay('Tuesday')}
          {this.renderDay('Wednesday')}
          {this.renderDay('Thursday')}
          {this.renderDay('Friday')}
          {this.renderDay('Saturday')}
          {this.renderDay('Sunday')}
        </div>
      </div>
    );
  }
}

class Weather extends React.Component {

    constructor(props){
        super(props);
        this.state = {
            selectedDay: {}
        };
        this.handler = this.handler.bind(this);
    }

    handler(day){
        this.setState({
            selectedDay: day
        });
    }
  render() {

    let day = null;
    if(Object.keys(this.state.selectedDay) > 0){
        day = <Day
            humidity={selectedDay.humidity}
            temperature={selectedDay.temperature}
        />;
    }

    return (
      <div className="weather">
        <div className="weather-panel">
          <DayRow onDayChange={this.handler}/>
        </div>
        <div className="day">
            {day}
        </div>
      </div>
    );
  }
}
// ========================================

ReactDOM.render(<Weather />, document.getElementById('root'));