You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React JS:非父子关系的两个独立文件如何传递pikerdate变量

解决方案

因为两个组件没有父子层级,无法直接通过props传值,有三种常用实现方式:

方案1:使用React内置Context API(无需额外依赖)

React原生支持的跨组件传值方案,适合中小项目:

  1. 新建src/context/DateContext.js文件,代码如下:
import { createContext, useContext, useState } from 'react';
import moment from 'moment';

const DateContext = createContext();

export function DateProvider({ children }) {
  const [selectedDate, setSelectedDate] = useState(moment(new Date()).format("YYYY-MM-DD"));
  return (
    <DateContext.Provider value={{ selectedDate, setSelectedDate }}>
      {children}
    </DateContext.Provider>
  )
}

export const useDate = () => useContext(DateContext);
  1. 在根组件(一般是App.js)中用Provider包裹所有需要用到这个日期的组件:
import { DateProvider } from './context/DateContext';

function App() {
  return (
    <DateProvider>
      {/* 原有项目所有组件,包括Calendar和Diet组件都放在此处 */}
    </DateProvider>
  )
}
  1. 修改calendar.js代码,选中日期时更新Context的值:
import moment from "moment";
import TrackerByDate from "./traker_by_date/tabs";
import { useDate } from '../context/DateContext'; // 引入自定义hook

export default function Calender() {
  const [value] = useState(new Date());
  const [show, setTracker] = useState(false);
  const { setSelectedDate } = useDate(); // 取全局日期更新方法

  const [dateState, setDateState] = useState(new Date());
  const changeDate = (e) => {
    setDateState(e);
  };
  var pikerdate = moment(dateState).format("YYYY-MM-DD");
  function clickTracker(e) {
    setSelectedDate(pikerdate); // 点击日期时更新全局日期值
    setTracker(!show);
  }

  return (
    <>
      {show ? <TrackerByDate dataFromParent={pikerdate} /> : null}
      <div style={{ width: "260px" }} className="res-calendar">
        <Calendar
          className={["c1", "c2"]}
          onChange={changeDate}
          onClickDay={clickTracker}
          value={dateState}
        />
      </div>
    </>
  );
}
  1. 在diet.js中直接获取选中的日期:
import { useDate } from '../context/DateContext';

export default function Diet() {
  const { selectedDate } = useDate(); // 直接拿到最新选中的日期
  // 后续业务逻辑可直接使用该变量
}

方案2:使用轻量状态管理库Zustand(代码更简洁)

如果项目允许引入第三方依赖,Zustand比Context更简单,不需要嵌套Provider:

  1. 先安装依赖:npm install zustand
  2. 新建src/store/useDateStore.js:
import { create } from 'zustand';
import moment from 'moment';

const useDateStore = create((set) => ({
  selectedDate: moment(new Date()).format("YYYY-MM-DD"),
  setSelectedDate: (date) => set({ selectedDate: date }),
}));

export default useDateStore;
  1. 修改calendar.js:
// 其他引入不变
import useDateStore from '../store/useDateStore';

export default function Calender() {
  // 其他state不变
  const setSelectedDate = useDateStore(state => state.setSelectedDate);

  var pikerdate = moment(dateState).format("YYYY-MM-DD");
  function clickTracker(e) {
    setSelectedDate(pikerdate); // 点击时更新全局日期
    setTracker(!show);
  }
  // 其余return部分保持不变
}
  1. 在diet.js中取值:
import useDateStore from '../store/useDateStore';

export default function Diet() {
  const selectedDate = useDateStore(state => state.selectedDate);
  // 直接使用即可
}

方案3:自定义事件总线(适合临时快速实现)

如果不想修改全局结构,可以用事件发布订阅的方式实现,要注意组件销毁时取消监听避免内存泄漏:

  1. 新建src/utils/eventBus.js:
class EventBus {
  constructor() {
    this.events = {};
  }
  on(eventName, callback) {
    if (!this.events[eventName]) this.events[eventName] = [];
    this.events[eventName].push(callback);
  }
  emit(eventName, data) {
    if (this.events[eventName]) {
      this.events[eventName].forEach(cb => cb(data));
    }
  }
  off(eventName, callback) {
    if (this.events[eventName]) {
      this.events[eventName] = this.events[eventName].filter(cb => cb !== callback);
    }
  }
}

export default new EventBus();
  1. 修改calendar.js点击时发布事件:
// 其他引入不变
import eventBus from '../utils/eventBus';

function clickTracker(e) {
  eventBus.emit('dateChange', pikerdate); // 发布日期变更事件
  setTracker(!show);
}
  1. 在diet.js中监听事件:
import { useEffect } from 'react';
import eventBus from '../utils/eventBus';

export default function Diet() {
  useEffect(() => {
    const handleDateChange = (date) => {
      // 拿到最新的日期date,执行你的业务逻辑
      console.log('选中的日期:', date);
    }
    eventBus.on('dateChange', handleDateChange);
    // 组件销毁时取消监听
    return () => eventBus.off('dateChange', handleDateChange);
  }, [])
}

内容的提问来源于stack exchange,提问作者vivek kn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 17:57:03