javascript - 组件之间状态变化的问题

标签 javascript reactjs

我尝试构建日历,并有可能为当天添加注释。我的组件结构如下: App 组件是渲染主要 Build 组件的公共(public)组件。 Build 组件使用 CellBuild 组件来构建日历的日期和一个 DayEventBuilder,它将在单击单元格时显示。

我尝试通过单击更改 CellBuild 组件中生成器的“天”状态,然后更改 DayEventBuilder 的状态以显示实际日期。我在更改 DayEventBuilder 的状态时遇到问题,因为它不是由 Builder 的组件获取状态。

CellBuild 中的“日”状态只有在点击两次后才会改变。 DayEventBuilder 组件不从 Builder 获取任何状态。

应用组件

import 'bootstrap/dist/css/bootstrap.css';
import React from 'react';
import './App.css';
import Builder from './Components/Builder.js';


let helpDate = new Date();

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <Builder helpDate={helpDate}/>
      </div>
    );
  }
}

export default App;

构建器组件

          import React from 'react';
          import 'bootstrap/dist/css/bootstrap.css';
          import CellBuild from './CellBuild.js';
     import DayEventBuilder from './DayEventBuilder.js';
     import $ from 'jquery';



     let currentDate= new Date();
     let months =                ['January','February','March','April','May','June','July','August','September','October','November','December'];
     //let month = currentDate.getMonth(); //current month
     //let year = currentDate.getFullYear();   //current year



     //Builder calendar body
     class Builder extends React.Component {

         constructor(props) {
             super(props);
             this.state = {
                 dataState: this.props.helpDate,   //set date to build and display
             };
         }

         //help function to control date parameters in cell which is clicked
         clickCell=x=>{
             this.setState({day:x});
         };

         createTable =(data)=>{

             let helpDate = new Date(data.getFullYear(), data.getMonth(), data.getDate());    //help date for drawing
             let helpOther = new Date(data.getFullYear(), data.getMonth(), data.getDate());   //help date for build previous month days
             helpDate.setDate(1);
             helpOther.setDate(1);
             let table=[];    //create table container
             let rows=[];    //create rows container




             //outer loop for rows creating (filling rows container)
             for(let i=0;i<6;i++){
                 let cells=[];   //create empty cells container

                 //inner loop for cells creating in row (filling cells container)
                 for (let j=0;j<7;j++){

                     //loop for draw previous month days and padding current 1st days relative days of week
                     if(i===0&&j<helpDate.getDay()-1){
                         helpOther.setDate(-helpDate.getDay()+2+j);

                         cells.push(<CellBuild date={helpOther.getDate()} month={helpOther.getMonth()} isNowDate="numbers otherMonth"/>);
                     }
                     //continue drawing calendar
                     else{
                         //if current month
                         if(helpDate.getMonth()===data.getMonth()){

                             //checking for today
                                            if(helpDate.getDate()===currentDate.getDate()&&helpDate.getMonth()===currentDate.getMonth()&&helpDate.getFullYear()===currentDate.getFullYear()){

                                 cells.push(<CellBuild clickCell={this.clickCell} date={helpDate.getDate()} month={helpDate.getMonth()} isNowDate="numbers nowDate"/>); //join cell to cells container
                        }
                             else{

                            cells.push(<CellBuild clickCell={this.clickCell} date={helpDate.getDate()} month={helpDate.getMonth()} isNowDate="numbers" />); //join cell to cells container

                        }
                    }
                    //next month days
                    else{
                        cells.push(<CellBuild clickCell={this.clickCell} date={helpDate.getDate()} month={helpDate.getMonth()} isNowDate="numbers otherMonth" />); //join cell to cells container
                    }
                    helpDate.setDate(helpDate.getDate()+1);
                }

            }
            rows.push(<tr>{cells}</tr>);    //join filled cells  container to rows container (join a row)
        }

        table.push(<table className="main col-lg-12 col-md-12 col-sm-12 col-xs-12"><thead><tr><th colSpan={2}><button className="decrease" onClick=
            {() =>
            {
                data.setMonth(data.getMonth()-1);
                this.setState({dataState:data});
            }}>&larr;</button><div className="head">{months[data.getMonth()]}</div><div className="head">{data.getFullYear()}</div><button className="increase" onClick=
            {() =>
            {
                data.setMonth(data.getMonth()+1);
                this.setState({dataState:data});
            }}>&rarr;</button></th></tr></thead><tbody>{rows}</tbody></table>);  //join filled rows  container to table and make header

        return table;
    };



    render() {
        return (
            <div className="container">
                <div className="calendar">{this.createTable(this.state.dataState)}</div>
                <DayEventBuilder day={this.state.day}/>
            </div>
        )
    }
}


export default Builder;

细胞构建

import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import $ from 'jquery';

//holidays list

let holidays = [
    {id:0,
    name:"New year",
    date:'01.01'},
    {id:1,
    name:"Christmas",
    date:'01.07'},
    {id:2,
     name:"Men's day",
     date:'02.23'},
    {id:3,
     name:"Women's day",
     date:'03.08'},
    {id:4,
     name:"Labor day",
     date:'05.01'},
    {id:5,
     name:"Victory Day",
     date:'05.09'},
    {id:6,
     name:"Independence day",
     date:'07.03'},
    {id:7,
     name:"November revolution day",
     date:'11.07'}];


class CellBuild extends React.Component {


    constructor() {
        super();
        this.state = {
            holidaysState: holidays,
        };
    }

    render(){
        //do default cell value if not holiday
        let cell=<td tabIndex="0" onClick={() => {
            console.log(this.props.date);
            this.setState({day:this.props.date});    //set day in state to render actual DayEventBuilderComponent
            console.log(this.state.day);
            //this.setState({month:this.props.month});    //set day in state to render actual DayEventBuilderComponent
            this.props.clickCell(this.state.day);
            $(function () {
                $('table.main').css('opacity','.5');
                $('table.dayEvents').css('display','table');
            })

        }
        }><div tabIndex="0" className={this.props.isNowDate}><p>{this.props.date}</p></div></td>;

        //check for holiday day
        this.state.holidaysState.map(function(holiday){
            //create temporary date object from date parameter of holiday
            let tempDate = new Date(holiday.date);

            //if current day is holiday change a cell value for this day in calendar
            if(tempDate.getMonth()===this.props.month&&tempDate.getDate()===this.props.date ){
                cell=<td tabIndex="0" onClick={() => {
                    $(function () {
                        $('table.main').css('opacity','.5');
                        $('table.dayEvents').css('display','table');
                    });
                }
                } className="holiday"><div tabIndex="0" className={this.props.isNowDate}><p>{this.props.date}</p></div><p className="holiday">{holiday.name}</p></td>;
            }

        },this);  //give CellBuilder as the context of map-function

        return cell;
    }
}


export default CellBuild;

DayEventBuilder

import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import $ from 'jquery';


let events = [
    {id:0,
        date:"2019.01.20",
        name:"Event 1 for this day",
        time1:"15:00",
        time2:"19:00"
    },
 ];



class DayEventBuilder extends React.Component {



    constructor(props) {
        super(props);
        this.state = {
            day:this.props.day,             //take actual day and month of the clicked cell from CellBuild
            month:this.props.month,
        };
    }
    render(){
        let table=[];    //create table container
        let rows=[];    //create rows container
        let skip=0;   //skip <td> adding if needed

        //build table
        for (let i=0;i<25;i++){
            let cells=[];   //create empty cells container
            cells.push(<td>{i+':00'}</td>);



                if((i+':00')===events[0].time1){
                    let rowspan = events[0].time2.substring(0, 2)-events[0].time1.substring(0, 2);   //calculate how long will the event be
                    cells.push(<td rowSpan={rowspan} className="setEvent">{events[0].name}</td>);
                    skip=rowspan;   //set skip counter
                }

                if(skip<=0){   //if we finished skip <td> adding while event was
                    cells.push(<td onClick={() => {
                        $(function () {
                            $('table.main').css('opacity','.3');
                            $('table.dayEvents').css('opacity','.5');
                            $('.form').css('display', 'block');
                        })
                    }}/>);
                }
                --skip;

            rows.push(<tr>{cells}</tr>);
        }

        //create table and create exit button from events list
        //console.log('DayEventBuilder state.day ='+this.state.day);
        table.push(<table className="dayEvents col-lg-6 col-md-8 col-sm-10 col-xs-10"><thead><tr><th>{this.state.day}</th><th><button onClick={() => {
            $(function () {
                $('table.main').css('opacity','1');
                $('table.dayEvents').css('display','none');
            })
        }
        }>&#215;</button></th></tr></thead><tbody>{rows}</tbody></table>);


        return (<div>
                    <div>{table}</div>
                    <div className="form col-lg-6 col-md-6 col-sm-8 col-xs-8">
                        <button onClick={() => {
                            $(function () {
                                $('table').css('display', 'table');
                                $('.form').css('display', 'none');
                                $('table.dayEvents').css('opacity','1');
                                $('table.main').css('opacity','.5');
                            })
                        }}>&larr;</button>
                        <form>
                            <fieldset>
                                <select className="form-control">
                                    <option value="one">One</option>
                                    <option value="two">Two</option>
                                    <option value="three">Three</option>
                                    <option value="four">Four</option>
                                    <option value="five">Five</option>
                                </select>
                                <legend>Add the event</legend>
                                <p>Description <input name="login"/></p>
                                <p><input type="submit" value="Add"/></p>
                            </fieldset>
                        </form>
                    </div>
            </div>);
    }
}

export default DayEventBuilder;

最佳答案

这可能是 CellBuild 单击处理程序中的问题。

此代码无法按预期工作,因为 setState是异步的。

() => {
            this.setState({day:this.props.date});
            this.props.clickCell(this.state.day);    
        }

尝试改成这样

() => {
            this.setState({day:this.props.date});
            this.props.clickCell(this.props.date);    
        }

此外,将 jqueryreact 一起使用也是一种不好的做法。

关于javascript - 组件之间状态变化的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54179595/

相关文章:

javascript - spread 元素在这里起什么作用

javascript - 循环组件的所有实例,记录每个状态

javascript - 非常基本的 Javascript 代码无法运行

javascript - 何时使用与 Electron react

javascript - 限制在 loadmore 上不起作用

javascript - 如何在获取数据时在 React Redux 应用程序中显示加载指示器?

ReactJs 切换按钮打开菜单

javascript - Reactjs 的bundle.js 中 Uncaught Error

javascript - 使用jquery根据用户点击的链接id动态创建文件路径

javascript - 桶文件、webpack 和 jest