简体   繁体   English

如何在 React Hooks 中更改 Provider 的值

[英]How to Change Value of Provider in React Hooks

I currently have this practice code that uses Context and Memo Hooks API我目前有这个使用上下文和备忘录挂钩 API 的练习代码

codesandbox密码箱

Here is a code snippet这是一个代码片段

export const InputContext = createContext()

export const ParentProvider = ({ initialValues, children }) => {
    console.log(initialValues)
    const [values, setValues ] = useState(initialValues);
    const value = {
        values,
        setValues
    }
    return <InputContext.Provider value={value}>{children}</InputContext.Provider>
}

What I want is to update the value of array that holds indicators using Context API after I click edit.我想要的是在单击编辑后使用上下文 API 更新包含指标的数组的值。

The problem is that I can't access the Context after accessing through the memo问题是通过备忘录访问后我无法访问上下文

Using useContext you need to pass the entire context object (not only Consumer ).使用useContext您需要传递整个context object (不仅是Consumer )。 And just use it like this像这样使用它

const Component = () =>{
    const context = useContext(InputContext)
    const { values, setValues } = context

    const handleChange = () => setValues('foo')        

    return(
        <>
            {values}
            <button onClick={handleChange}>Change</button>
        </>
    )
}

You'll need to wrap all components that need access to the context with the provider.您需要使用提供者包装所有需要访问上下文的组件。 Something like this...像这样的东西...

编辑淘气雷-msxz1


ParentProvider.js ParentProvider.js

import React, { createContext, useState } from "react";

const INITIAL_STATE = [];
export const InputContext = createContext(INITIAL_STATE);

export const ParentProvider = ({ children }) => {
  const [values, setValues] = useState(INITIAL_STATE);

  React.useEffect(() => {
    console.log("[parentprovider.js]::new values", values);
  }, [values]);

  return (
    <InputContext.Provider value={{ values, setValues }}>
      {children}
    </InputContext.Provider>
  );
};

ShowIndicator.js ShowIndicator.js

import React, { memo, useContext, useState } from "react";
import { Button } from "react-bootstrap";
import { InputContext } from "./ParentProvider";

const ShowIndicator = memo(
  ({ name, context }) => {
    const [_name, _setName] = useState(name);
    const [text, setText] = useState();
    const { values, setValues } = useContext(InputContext);

    const editData = e => {
      let newValues = [...values];
      newValues[values.indexOf(_name)] = text;
      setValues(newValues);
      _setName(text);
    };

    const handleTextChange = e => setText(e.target.value);

    const renderDatas = () => {
      return (
        <div key={_name} className="d-flex justify-content-between">
          <input
            className="d-flex align-items-center"
            defaultValue={_name}
            onChange={handleTextChange}
          />
          <div>
            <Button
              variant="info"
              style={{ marginRight: "10px" }}
              onClick={editData}
            >
              Edit
            </Button>
            <Button variant="dark">Delete</Button>
          </div>
        </div>
      );
    };

    return <div style={{ marginBottom: "5px" }}>{renderDatas()}</div>;
  },
  (prev, next) => prev.value === next.value
);

export default ShowIndicator;

App.js应用程序.js

import React, { useState, useContext } from "react";
import "./styles.css";
import { Form, Button, Container } from "react-bootstrap";
import ShowIndicator from "./ShowIndicator";
import { InputContext } from "./ParentProvider";

function App() {
  const [curText, setCurText] = useState("");
  const { values, setValues } = useContext(InputContext);

  const onSubmit = e => {
    e.preventDefault();
    if (!values.includes(curText)) {
      values ? setValues([...values, curText]) : setValues([curText]);
      setCurText("");
    }
  };

  const onChange = e => setCurText(e.target.value);

  return (
    <div>
      <Container style={{ marginTop: "10px", textAlign: "center" }}>
        <div>Add Indicator</div>
        <Form inline onSubmit={onSubmit} style={{ marginBottom: "1rem" }}>
          <Form.Control
            style={{ flex: "1 0 0" }}
            onChange={onChange}
            value={curText}
          />
          <Button type="submit" variant="success">
            Submit
          </Button>
        </Form>
        {values &&
          values.map((data, index) => {
            return <ShowIndicator key={index} name={data} />;
          })}
      </Container>
    </div>
  );
}

export default App;

index.js index.js

import React from "react";
import App from "./App";
import { render } from "react-dom";
import { ParentProvider } from "./ParentProvider";

render(
  <ParentProvider>
    <App />
  </ParentProvider>,
  document.getElementById("root")
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM