Home > Blockchain >  passing object using context and doing iteration with map
passing object using context and doing iteration with map

Time:10-02

This is a simple question but I couldn't reach the final result after a lot of attempts. The problem is that I want to pass an object in context and use it in another file. And then do an iteration and create a specific element for each value.

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>
);

CodePudding user response:

You should make sure that the Activity.jsx component is wrapped with context provider, to get the proper value from the context.

I tried in this codesandbox, and it's working properly. You can refer to this and check what you are missing.

CodePudding user response:

I believe this is what you want:

// Sharing data through context

Context file:

// 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;

Hook to read from context:

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

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

export default useDataContext;

Child Element where you want to receive the value from context:

// 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;

And the App container:

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

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

I've created a sandbox for you to test.

  • Related