簡體   English   中英

在 React 組件之間共享數據

[英]Sharing data between React components

我在 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;

有多種方法可以在組件之間共享數據。 您可以使用以下選項之一:

  • 如果要向其傳遞數據的組件是SearchForm組件的子組件,則可以將其作為prop傳遞。

  • If you are managing state via redux, you can connect components to the redux store and get the required data from the redux store in your components.

  • 您還可以使用 React 的Context API在可能具有或不具有父子關系的組件之間共享公共數據。

  • 如果需要SearchForm組件數據的組件是SearchForm組件的父組件,可以將回調function作為prop傳遞給SearchForm組件,當SearchForm組件中有數據時,調用回調function,作為prop接收,並將數據作為參數傳遞給該回調 function。

我會按照優素福的建議去做。

SearchForm 應該有兩個道具:nameservers handleSubmit

(這將使編寫 Storybook 故事和任何測試變得容易)。

然后為 SearchForm 創建一個包裝器,該包裝器執行 API 調用 (handleSubmit) 並在上下文中設置名稱服務器。 現在可以在應用程序的其他地方訪問名稱服務器。

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) 上,您從服務器檢索數據。 獲得數據后,讓我們將數據發送到 store 中共享

/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 商店中有名稱服務器,您可以輕松地從另一個組件中獲取它,如下所示:

其他組件.js

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

如果您在OtherComponent中的某處記錄名稱服務器,您將看到在MyComponent中檢索到的數據。 驚人的!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM