【问题标题】:Sharing data between React components在 React 组件之间共享数据
【发布时间】:2020-11-08 21:52:43
【问题描述】:

我在 React 中有一个搜索表单,它执行 API 调用并使用 useState() React 挂钩将名为名称服务器的数据保存在状态。

我正在尝试确定如何将这些数据传递给另一个组件,以便将数据用于在页面上的其他位置呈现。

目前,我只是在搜索表单下方显示的返回块中输出数据。

import React, { useState } from "react";
import { Spinner, Form, Button, Container, Col } from "react-bootstrap";
import { FaSearch } from "react-icons/fa";

const SearchForm: React.FC = () => {
  const [domain, setDomain] = useState("");
  const [loading, setLoading] = useState(false);
  const [nameservers, setNameservers] = useState([]);
  const [submitted, setSubmitted] = useState(false);

  const formText = "Search for a domains";

  const handleChange = (event: any) => {
    setDomain(event.target.value);
  };

  const handleSubmit = (event: any) => {
    event.preventDefault();
    setLoading(true);
    setSubmitted(true);
    console.log(domain);

    fetch(`https://dns.google.com/resolve?name=${domain}&type=NS`)
      .then(results => results.json())
      .then(data => {
        setLoading(false);
        if (data && data.Answer) {
          data.Answer.sort((a: any, b: any) => a.data.localeCompare(b.data));
          setNameservers(data.Answer);
        }
      });
  };

  return (
    <>
      <Form onSubmit={handleSubmit}>
        <Form.Row>
          <Col />
          <Col>
            <Form.Control
              type="text"
              placeholder={formText}
              value={domain}
              onChange={handleChange}
              autoFocus
              required
            />
          </Col>
          <Col>
            <Button variant="primary" type="submit">
              <FaSearch /> Search
            </Button>
          </Col>
        </Form.Row>
      </Form>
      <hr />
      {submitted &&
        nameservers.map((server: any, index: number) => (
          <li key={index}>{server.data}</li>
        ))}

      {submitted && nameservers.length === 0 && <small>Error</small>}

      {loading && (
        <Container className="text-center">
          <Spinner animation="grow" size="sm" />
          <Spinner animation="grow" size="sm" />
          <Spinner animation="grow" size="sm" />
        </Container>
      )}
    </>
  );
};

export default SearchForm;

【问题讨论】:

    标签: javascript reactjs jsx


    【解决方案1】:

    有多种方法可以在组件之间共享数据。您可以使用以下选项之一:

    • 如果要向其传递数据的组件是SearchForm 组件的子组件,则可以将其作为prop 传递。

    • 如果您通过 redux 管理状态,您可以将组件连接到 redux 存储并从组件中的 redux 存储中获取所需的数据。

    • 您还可以使用 React 的 Context API 在可能具有或不具有父子关系的组件之间共享公共数据。

    • 如果需要来自SearchForm组件的数据的组件是SearchForm组件的父组件,则可以将回调函数作为prop传递给SearchForm组件,并且当@中有数据时987654328@ 组件,调用回调函数,作为prop 接收,并将数据作为参数传递给该回调函数。

    【讨论】:

    • 如果是SearchForm的parent,也可以通过props传值,使用回调函数。
    【解决方案2】:

    我会按照优素福的建议去做。

    SearchForm 应该有两个道具: 域名服务器 处理提交

    (这将使编写故事书故事和任何测试变得容易)。

    然后为 SearchForm 创建一个包装器,该包装器执行 API 调用 (handleSubmit) 并在上下文中设置名称服务器。现在可以在应用程序的其他地方访问名称服务器。

    【讨论】:

      【解决方案3】:

      Ciao,当我想在组件之间共享数据时,我使用React-Redux。 让我们举个例子: 假设您要共享服务器(名称服务器)接收到的数据。 首先安装 react-redux:

      npm install react-redux
      npm install redux
      npm install @reduxjs/toolkit
      

      现在我们必须创建reduceraction: 假设您将组件放在名为“/components/MyComponent”的文件夹中。创建一个名为 MyReducer.js 的文件。

      /components/MyComponent/MyReducer.js

      import { createReducer } from '@reduxjs/toolkit';
      
      const initialState = {
        nameservers: undefined,
      };
      
      const LoginReducer = createReducer(initialState, {
         ["SET_NAMESERVERS"]: (state, action) => {
             state.nameservers= action.payload.nameservers;
         },
      })
      
      export default MyReducer;
      

      现在,在同一个文件夹中,创建一个名为 MyAction.js 的文件

      /components/MyComponent/MyAction.js

      export const setNameServers = data => ({
         type: "SET_NAMESERVERS",
         payload: { nameservers: data }
      });
      

      然后创建store: 在您的项目根目录上创建一个名为 redux 的文件夹。在其中创建一个名为store 的文件夹。然后在这个文件夹中创建一个名为 index.js 的文件。

      redux/store/index.js

      import { createStore, combineReducers } from "redux";
      import MyReducer from '../../components/MyComponent/MyReducer';
      
      const reducers = combineReducers({
        MyReducer,
      });
      
      const store = createStore(reducers);
      
      export default store;
      

      现在在根文件夹的 index.js 文件中,让我们传递已经创建的商店:

      index.js

      ...
      import { Provider } from 'react-redux';
      import store from "./redux/store";
      
      ReactDOM.render((
       <Provider store={store}>
          <App />
       </Provider>
      ), document.getElementById('root') || document.createElement('div'));
      

      我们几乎完成了。在您的组件 (MyComponent) 上,您从服务器检索数据。获得数据后,让我们发送数据以共享到商店

      /components/MyComponent/MyComponent.js

      ...
      import { useDispatch } from 'react-redux';
      import { setNameServers } from './MyComponentAction';
      
      const MyComponent: React.FC = () => {
         const [nameservers, setNameservers] = useState([]);
         const dispatch = useDispatch();
         ....
         const handleSubmit = (event: any) => {
           ...
      
      fetch(`https://dns.google.com/resolve?name=${domain}&type=NS`)
      .then(results => results.json())
      .then(data => { 
        setLoading(false);
        if (data && data.Answer) {
          data.Answer.sort((a: any, b: any) => a.data.localeCompare(b.data));
          setNameservers(data.Answer);
          dispatch(setNameServers(data.Answer)); // here the magic
        } 
        });
       };
         
      };
      

      完成!现在你的 react redux 商店里有了域名服务器,你可以很容易地从另一个组件中获取它,如下所示:

      OtherComponent.js

      import { useSelector } from 'react-redux';
      const OtherComponent: React.FC = () => {
         const nameservers = useSelector(state => state.MyReducer.nameservers);
      };
      

      如果您在OtherComponent 的某个位置记录名称服务器,您将看到在MyComponent 中检索到的数据。太棒了!

      【讨论】:

        猜你喜欢
        • 2019-05-16
        • 2016-10-23
        • 2020-08-31
        • 2021-12-06
        • 2019-01-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多