将类组件转换为功能组件

时间:2020-12-28 14:17:52

标签: reactjs

我想在函数组件中改变这个类组件:

import React from "react";
import "./styles.css";
import DayPicker, { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleDayClick = this.handleDayClick.bind(this);
    this.state = {
      selectedDays: []
    };
  }

  handleDayClick(day, { selected }) {
    const { selectedDays } = this.state;
    if (selected) {
      const selectedIndex = selectedDays.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      selectedDays.splice(selectedIndex, 1);
    } else {
      selectedDays.push(day);
    }
    this.setState({ selectedDays });
  }

  render() {
    return (
      <div>
        {console.log(this.state.selectedDays)}
        <DayPicker
          selectedDays={this.state.selectedDays}
          onDayClick={this.handleDayClick}
        />
      </div>
    );
  }
}

演示:https://codesandbox.io/s/agitated-chaum-0qss8?file=/src/App.js:0-944
我这样做了:

 const [selectedDays, setSelectedDays] = useState([])

    const handleDayClick = (day, {selected}) => {
        if (selected) {
            const selectedIndex = selectedDays.findIndex(selectedDay =>
                DateUtils.isSameDay(selectedDay, day)
            );
            console.log('test',selectedDays);

            selectedDays.splice(selectedIndex, 1);
        } else {
            // selectedDays.push(day)
            setSelectedDays([...selectedDays,day]);

        }
    }
    console.log(selectedDays);
    return (
        <div className="er">
            <DayPicker
                selectedDays={selectedDays}
                onDayClick={handleDayClick}
            />
        </div>
    );
};

问题:当我选择 1 个日期时,日期变为活动状态,但是当我再次单击它时,它不会变回非活动状态?问题是什么以及如何解决?

5 个答案:

答案 0 :(得分:0)

这对您有用。

import React, {useState} from "react";
import "./styles.css";
import DayPicker, { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";

export default App =()=> {
  const [selectedDays, setSelectedDays] = useState([]);

  const handleDayClick=(day, { selected })=> {
    
    if (selected) {
      const selectedIndex = selectedDays.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      selectedDays.splice(selectedIndex, 1);
    } else {
      selectedDays.push(day);
    }
    setSelectedDays( selectedDays );
  }

 
    return (
      <div>
        {console.log(this.state.selectedDays)}
        <DayPicker
          selectedDays={selectedDays}
          onDayClick={handleDayClick}
        />
      </div>
    );
  
}

答案 1 :(得分:0)

已经更新了答案,之前我实际上是在改变状态,这不是最佳实践。

import React, { useState } from "react";
import "./styles.css";
import DayPicker, { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";

export default function Class1() {
  const [selectedDays, setSelectedDays] = useState([]);
  function handleDayClick(day, { selected }) {
    const selectedDaysNew = [...selectedDays];
    if (selected) {
      const selectedIndex = selectedDaysNew.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      selectedDaysNew.splice(selectedIndex, 1);
    } else {
      selectedDaysNew.push(day);
    }
    setSelectedDays(selectedDaysNew);
  }

  return (
    <div>
      {console.log(selectedDays)}
      <DayPicker selectedDays={selectedDays} onDayClick={handleDayClick} />
    </div>
  );
}

答案 2 :(得分:0)

在评论中说话有点困难,所以我要发布一个答案。

如果你这样做会改变什么吗(这是一个问题):

const handleDayClick=(day, { selected })=> {
const currentState = [...selectedDays];

    if (selected) {
      const selectedIndex = currentState.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      currentState.splice(selectedIndex, 1);
    } else {
      currentState.push(day);
    }
    setSelectedDays(currentState);
  }

答案 3 :(得分:0)

你不应该改变原始状态数组,首先从状态数组创建一个副本:

const handleDayClick = (day, {selected}) => {
  setSelectedDays(prevSelected => {
    const selectedDays = [...prevSelected]
    if (selected) {
      const selectedIndex = selectedDays.findIndex(selectedDay =>
          DateUtils.isSameDay(selectedDay, day)
      );
      console.log('test',selectedDays);

      selectedDays.splice(selectedIndex, 1);
      return selectedDays
    } else {
      return [...selectedDays,day]
    }
  })
}

答案 4 :(得分:0)

切勿直接改变状态您正在直接使用静音状态变量执行某些操作,这可能会导致未意识到的错误。

请参考下面的链接 Why Not To Modify React State Directlystack-overflow 这些概念对组件中的类状态或 useState 都适用。

我只是在继续之前创建了一个新数组,它工作正常。 codesandbox

import React, { useState } from "react";
import "./styles.css";
import DayPicker, { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";

export default () => {
  const [selectedDays, setSelectedDays] = useState([]);
  const handleDayClick = (day, { selected }) => {
    const selectedDaysTemp = [...selectedDays]; // here is the change creating the new array 
    if (selected) {
      const selectedIndex = selectedDaysTemp.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      selectedDaysTemp.splice(selectedIndex, 1);
    } else {
      selectedDaysTemp.push(day);
    }
    setSelectedDays(selectedDaysTemp);
  };
  return (
    <div>
      {console.log(selectedDays)}
      <DayPicker selectedDays={selectedDays} onDayClick={handleDayClick} />
    </div>
  );
};