使用上下文传递对象并使用地图进行迭代

passing object using context and doing iteration with map

这是一个简单的问题,但我尝试了很多次都无法得出最终结果。问题是我想在上下文中传递一个对象并在另一个文件中使用它。然后进行迭代并为每个值创建一个特定元素。

App.jsx

const [activities, setActivity] = useState([
    {
        key: Math.random() * Math.random(),
        name: 'Hello',
    }
]);
const inputValue = useRef(null);
const addActivity = () => {
    const activity = {
        key: Math.random() * Math.random(),
        name: inputValue.current.value,
    };
    setActivity(activities.concat(activity));
};

const value = {
    // I want to pass this parameter - only activities has problem (Activity.jsx <h1>)
    // I can't achieve activities.name in Activity.jsx
    activities: [...activities],
    functions: {
        addActivity: addActivity
    },
    ref: {
        inputValue: inputValue
    }
};

<Context.Provider
    value={value}
>

Context.js

export const Context = createContext();

Activity.jsx

const { activities, functions, ref } = useContext(Context);
return (
    <section className="activity-container">
        <input type="text" ref={ref.inputValue} />
        <button onClick={functions.addActivity}>add!</button>
        {
            activities.map(activity => (
                <h1>activity.name</h1>
            ))
        }
    </section>
);

您应该确保 Activity.jsx 组件使用上下文提供程序包装,以便从上下文中获取正确的值。

我试过这个 codesandbox,它工作正常。你可以参考这个,看看你缺少什么。

我相信这就是你想要的:

// 通过上下文共享数据

上下文文件:

// Context.js
import React, { useState, useRef, createContext } from "react";

export const DataContext = createContext();
const getRandom = () => Math.random() * Math.random();
const defaultValue = {
  key: getRandom(),
  name: "Hello"
};

const ContextProvider = ({ children }) => {
  const [activities, setActivity] = useState([defaultValue]);
  const inputValue = useRef(null);

  const addActivity = () => {
    const activity = {
      key: getRandom(),
      name: inputValue.current.value
    };
    setActivity([...activities, activity]);
  };

  const value = {
    activities: [...activities],
    functions: { addActivity },
    ref: { inputValue }
  };

  return <DataContext.Provider value={value}>{children}</DataContext.Provider>;
};

export default ContextProvider;

挂钩以从上下文中读取:

// useDataContext
import { useContext } from "react";
import { DataContext } from "./Context";

const useDataContext = () => {
  const contextValue = useContext(DataContext);
  return contextValue;
};

export default useDataContext;

您想从上下文中接收值的子元素:

// Child.js
import React from "react";
import useDataContext from "./useDataContext";

const Child = () => {
  const data = useDataContext();
  
  return (
    <>
      {data.activities.map((val, idx) => (
        <div key={idx}>Name is {val.name}</div>
      ))}
    </>
  );
};

export default Child;

和应用程序容器:

// App.js
import Child from "./Child";
import ContextProvider from "./Context";

export default function App() {
  return (
    <div className="App">
      <ContextProvider>
        <Child />
      </ContextProvider>
    </div>
  );
}

我创建了一个 sandbox 供您测试。