如何从外部访问 useEffect 块内部的数据?

问题描述 投票:0回答:1

基本上,我有一个 DateView 组件,我从中检索 ChooseCalendar 组件中的日期。但是,我有在 useEffect 块中从 DateView 检索此数据的代码,因为我正在将作为 useState 一部分的 dateType 变量传递给组件。这个问题是在 ChooseCalendar 组件中我无法访问 DateView 组件的道具中的数据。我要访问的数据是 onDateTypeChange 存储的值。有没有办法解决这个问题,以便我可以访问这些数据?

这是我的 ChooseCalendar.js 组件:

import React, { useState, useEffect, useCallback } from 'react';
import DateView from '../components/DateView';

export default function ChooseCalendar(props) {
  const [calendarType, setCalendarType] = useState('day');
  const [calendarView, setCalendarView] = useState(null);
  const [selectedDate, setSelectedDate] = useState(null);

  // Retrieve dropdown value and pass it to props
  const handleCalendarTypeChange = (event) => {
    const newCalendarType = event.target.value;
    setCalendarType(newCalendarType);
    props.onCalendarTypeChange(newCalendarType);
  };

  const handleDateTypeChange = useCallback((date) => {
    setSelectedDate(date);
  }, []);
  
  useEffect(() => {
    let newCalendarView;
    if (calendarType === 'day') {
      newCalendarView = <DateView dateType="day" onDateTypeChange={handleDateTypeChange} />;
    } else if (calendarType === 'week') {
      newCalendarView = <DateView dateType="week" onDateTypeChange={handleDateTypeChange} />;
    } else if (calendarType === 'month') {
      newCalendarView = <DateView dateType="month" onDateTypeChange={handleDateTypeChange} />;
    }
    setCalendarView(newCalendarView);
  }, [calendarType, handleDateTypeChange]);

  useEffect(() => {
    if (selectedDate) {
      props.onDateTypeChange(selectedDate);
      console.log('Calendar selected date : ', selectedDate);
    }
  }, [selectedDate, props.onDateTypeChange]);

  return (
    <section className="border-4 rounded-lg p-2 px-28 bg-red-400 text-slate-800">
      <h2 className="text-xl font-bold">Calendar Settings</h2>
      <p className="font-semibold mb-1">Change your calendar settings</p>
      <select onChange={handleCalendarTypeChange} className="w-56 border-4 rounded p-2 bg-white hover:bg-gray-100 text-slate-800">
        <option value="day">Day View</option>
        <option value="week">Week View</option>
        <option value="month">Month View</option>
      </select>
      {calendarView}
    </section>
  );
}

这是我的 DateView.js 组件:

export default function dateViewDisplayer(props){
  const dateType = props.dateType;

  const handleDateTypeChange = (event) => {
    const date = event.target.value;
    props.onDateTypeChange(date);
  };

  if (dateType === 'day'){
    return (
      <section>
        <p className="font-semibold mb-1">Choose your day</p>
        <input onChange={handleDateTypeChange} className="w-56 border-4 rounded p-2 bg-white hover:bg-gray-100 text-slate-800" type="date" />
      </section>
    );
  }

  if (dateType === 'week'){
    return (
      <section>
        <p className="font-semibold mb-1">Choose your week</p>
        <input onChange={handleDateTypeChange} className="w-56 border-4 rounded p-2 bg-white hover:bg-gray-100 text-slate-800" type="week" />
      </section>
    );
  }

  if (dateType === 'month'){
    return (
      <section>
        <p className="font-semibold mb-1">Choose your month</p>
        <input onChange={handleDateTypeChange} className="w-56 border-4 rounded p-2 bg-white hover:bg-gray-100 text-slate-800" type="month" />
      </section>
    );
  }
}
javascript reactjs next.js react-hooks components
1个回答
0
投票

我想知道使用条件渲染是否比将新组件存储在状态中更容易。试一试怎么样?请注意,不再需要

calenderView
状态和
useEffect
,您现在可以像往常一样传递所需的
handleDateTypeChange
道具。

import React, { useState, useEffect, useCallback } from 'react';
import DateView from '../components/DateView';

export default function ChooseCalendar(props) {
  const [calendarType, setCalendarType] = useState('day');
  const [selectedDate, setSelectedDate] = useState(null);

  // Retrieve dropdown value and pass it to props
  const handleCalendarTypeChange = (event) => {
    const newCalendarType = event.target.value;
    setCalendarType(newCalendarType);
    props.onCalendarTypeChange(newCalendarType);
  };

  const handleDateTypeChange = useCallback((date) => {
    setSelectedDate(date);
  }, []);

  useEffect(() => {
    if (selectedDate) {
      props.onDateTypeChange(selectedDate);
      console.log('Calendar selected date : ', selectedDate);
    }
  }, [selectedDate, props.onDateTypeChange]);

  return (
    <section className='border-4 rounded-lg p-2 px-28 bg-red-400 text-slate-800'>
      <h2 className='text-xl font-bold'>Calendar Settings</h2>
      <p className='font-semibold mb-1'>Change your calendar settings</p>
      <select
        onChange={handleCalendarTypeChange}
        className='w-56 border-4 rounded p-2 bg-white hover:bg-gray-100 text-slate-800'
      >
        <option value='day'>Day View</option>
        <option value='week'>Week View</option>
        <option value='month'>Month View</option>
      </select>
      {calendarType === 'day' && (
        <DateView dateType='day' onDateTypeChange={handleDateTypeChange} />
      )}

      {calendarType === 'week' && (
        <DateView dateType='week' onDateTypeChange={handleDateTypeChange} />
      )}

      {calendarType === 'month' && (
        <DateView dateType='month' onDateTypeChange={handleDateTypeChange} />
      )}
    </section>
  );
}

更新:

或者更简单,因为它看起来像

dateType
calendarType
一样,你能不能这样做(缩短以突出显示返回值的变化):

...
export default function ChooseCalendar(props) {
  ...
  return (
    <section className='border-4 rounded-lg p-2 px-28 bg-red-400 text-slate-800'>
      <h2 className='text-xl font-bold'>Calendar Settings</h2>
      <p className='font-semibold mb-1'>Change your calendar settings</p>
      <select
        onChange={handleCalendarTypeChange}
        className='w-56 border-4 rounded p-2 bg-white hover:bg-gray-100 text-slate-800'
      >
        <option value='day'>Day View</option>
        <option value='week'>Week View</option>
        <option value='month'>Month View</option>
      </select>
        <DateView dateType={calendarType} onDateTypeChange={handleDateTypeChange} />
    </section>
  );
}

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.