从子组件访问父项中的useEffect

时间:2020-03-28 19:42:05

标签: reactjs react-hooks

我正在使用react并试图找出如何从子组件中触发useEffect(在父项上)。

我有一个子组件,其中包含一个模态,该模态带有传递到数据库的输入字段。

import React, { useState } from 'react';
import { Modal, Button, Form } from 'react-bootstrap';

const AddContact = () => {

  // Modal Setup
  const [ showModal, setShowModal ] = useState(false);
  const handleClose = () => setShowModal(false);
  const handleShow = () => setShowModal(true);

  // Using state to hold the values for each field in the form
  const [first, setFirst] = useState('');
  const [last, setLast] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault(); // prevents form default action
    const addContact = async () => {
      const result = await fetch('/api/crm/add', {
      method: 'POST',
      body: JSON.stringify({ first_name: first, last_name: last }),
      headers: {
        'Content-Type': 'application/json',
      }
      });
      const body = await result.json();
    }
    addContact();
    handleClose();
  };

  return (
    <>
      <Button onClick={handleShow} variant="primary" size="sm">Add Contact</Button>
      <Modal show={showModal} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Add Contact</Modal.Title>
        </Modal.Header>
        <Modal.Body>
            <label for="formfirst">First Name: </label><br />
            <input 
              id="formfirst" 
              name="formfirst" 
              type="text" 
              value={first} 
              onChange={e => setFirst(e.target.value)}
            />
            <br/>
            <label for="formlast">Last Name: </label><br />
            <input 
              id="last" 
              name="last" 
              type="text" 
              value={last} 
              onChange={e => setLast(e.target.value)} 
            /> <br/>
            <Form.Group>

            </Form.Group>
        </Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleClose}>Cancel</Button>
          <Button variant="primary" onClick={handleSubmit}>Submit</Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}
export default AddContact;

父组件具有要刷新的数据表,以便显示当前数据:

import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import { Table } from 'react-bootstrap';

import AddContactForm from '../components/AddContactForm';

// React-Table
import {
  useTable,
} from 'react-table'

const ContactsPage = () => { 
  const [ tableData, setTableData ] = useState([]);

  useEffect( () => {
    const fetchData = async () => {
      const result = await fetch(`api/crm/get`);
      const body = await result.json();
      setTableData(body);
    }
    fetchData();
  },[]);

  const columns = React.useMemo(
    () => [
          {
            Header: 'First Name',
            accessor: 'first_name',
          },
          {
            Header: 'Last Name',
            accessor: 'last_name',
          } 
          ... SIMPLIFIED FOR CONCISENESS
    ],
    []
  )

  function ReactTable({ columns, data }) {
    const {
      getTableProps,
      ... REMOVED SOME REACT-TABLE FOR CONCISENESS
    } = useTable({
      columns,
      data,
      })

    return (
      <>
        <h2>Contacts</h2>
        <hr></hr>
        <div>
          <AddContactForm />
        </div>

        <Table striped bordered hover size="sm" {...getTableProps()}>
         ... REMOVED TABLE TO CONCISENESS
        </Table>
      </>
    );
  }


  const data = React.useMemo(() => tableData)

  return (
    <Styles>
      <ReactTable columns={columns} data={data} />
    </Styles>
  )
}

export default ContactsPage;

我该如何实现?我尝试将useEffect挂钩连接到可以传递给子组件的函数中,但是出现一个错误,指出该新函数不是函数?

1 个答案:

答案 0 :(得分:1)

不确定将useEffect作为props传递是有意义的,而是将useEffect内部使用的函数作为props传递。在这里

useEffect( () => {
    const fetchData = async () => {
      const result = await fetch(`api/crm/get`);
      const body = await result.json();
      setTableData(body);
    }
    fetchData();
  },[]);

像这样重构它;

// Wrapped in useCallback otherwise it would be recreated each time 
// this component rerenders, hence triggering useEffect below
let fetchData = React.useCallback(async () => {
      const result = await fetch(`api/crm/get`);
      const body = await result.json();
      setTableData(body);
    },[])

useEffect(() => {
  fetchData();
},[fetchData]);

通过fetchData作为模态的道具,您可以在提交后调用它们。