如何从上下文 API 中的组件调用函数?

How to call functions from components in context API?

我刚开始在 React.JS 中使用 Context API,并且仍在学习中。我的导航栏子功能组件中有一个按钮,当按下该按钮时,我希望它将数据发送到函数中使用的上下文 api。 这是我的上下文 API

import {useState, createContext} from 'react'

export const ContextApi = createContext()

export const ApiProvider = props => {
    const [api, setApi] = useState({
        winners: [
            {
                id: 1930,
                winningTeam: "Uruguway",
                runnerUp: "Argentina",
                location: "Montevideo, Uruguay",
                Attendance: "80,000",
                score: "4-2"
            },
            {
                id: 1934,
                winningTeam: "Italy",
                runnerUp: "Czechoslovakia",
                location: "Rome, Italy",
                Attendance: "50,000",
                score: "2-1"
            },
            {
                id: 1938,
                winningTeam: "Italy",
                runnerUp: "Hungary",
                location: "Colombes, France",
                Attendance: "45,000",
                score: "4-2"
            },
            {
                id: 1950,
                winningTeam: "Uruguway",
                runnerUp: "Brazil",
                location: "Rio De Janeiro, Brazil",
                Attendance: "199,854",
                score: "2-1"
            },
            {
                id: 1954,
                winningTeam: "West Germany",
                runnerUp: "Hungary",
                location: "Bern, Switzerland",
                Attendance: "60,000",
                score: "3-2"
            },
            {
                id: 1958,
                winningTeam: "Brazil",
                runnerUp: "Sweden",
                location: "Solna, Sweden",
                Attendance: "51,800",
                score: "5-2"
            },
            {
                id: 1962,
                winningTeam: "Brazil",
                runnerUp: "Czechoslovakia",
                location: "Santiago, Chile",
                Attendance: "69,000",
                score: "3-1"
            },
            {
                id: 1966,
                winningTeam: "England",
                runnerUp: "West Germany",
                location: "London, England",
                Attendance: "96,924",
                score: "4-2"
            },
            {
                id: 1970,
                winningTeam: "Brazil",
                runnerUp: "Italy",
                location: "Mexico City, Mexico",
                Attendance: "107,412",
                score: "4-1"
            },
            {
                id: 1974,
                winningTeam: "West Germany",
                runnerUp: "Netherlands",
                location: "Munich, West Germany",
                Attendance: "75,200",
                score: "2-1"
            },
            {
                id: 1978,
                winningTeam: "Argentina",
                runnerUp: "Netherlands",
                location: "Buenos Aires, Argentina",
                Attendance: "71,483",
                score: "3-1"
            },
            {
                id: 1982,
                winningTeam: "Italy",
                runnerUp: "West Germany",
                location: "Madrid, Spain",
                Attendance: "90,000",
                score: "3-1"
            },
            {
                id: 1986,
                winningTeam: "Argentina",
                runnerUp: "West Germany",
                location: "Mexico City, Mexico",
                Attendance: "114,600",
                score: "3-2"
            },
            {
                id: 1990,
                winningTeam: "West Germany",
                runnerUp: "Argentina",
                location: "Rome, Italy",
                Attendance: "73,603",
                score: "1-0"
            },
            {
                id: 1994,
                winningTeam: "Brazil",
                runnerUp: "Italy",
                location: "Pasadena, United States",
                Attendance: "94,194",
                score: "0-0"
            },
            {
                id: 1998,
                winningTeam: "France",
                runnerUp: "Brazil",
                location: "Saint-Denis, France",
                Attendance: "80,000",
                score: "3-0"
            },
            {
                id: 2002,
                winningTeam: "Brazil",
                runnerUp: "Germany",
                location: "Yokohama, Japan",
                Attendance: "69,029",
                score: "2-0"
            },
            {
                id: 2006,
                winningTeam: "Italy",
                runnerUp: "France",
                location: "Berlin, West Germany",
                Attendance: "69,000",
                score: "1-1"
            },
            {
                id: 2010,
                winningTeam: "Spain",
                runnerUp: "Netherlands",
                location: "Johannesburg, South Africa",
                Attendance: "84,490",
                score: "1-0"
            },
            {
                id: 2014,
                winningTeam: "Germany",
                runnerUp: "Argentina",
                location: "Rio De Janeiro, Brazil",
                Attendance: "74,738",
                score: "1-0"
            },
            {
                id: 2018,
                winningTeam: "France",
                runnerUp: "Croatia",
                location: "Moscow, Russia",
                Attendance: "78,011",
                score: "4-2"
            }
            
        ],
        country: null
    })
    const addCountry = (country) => {
        console.log(country)
    }
    return (
        <ContextApi.Provider addCountry={addCountry()} value={{winnerData: [api, setApi]}}>{props.children}</ContextApi.Provider>
    )
}

这是我的主文件

const Main = () => {
    return (
        <ApiProvider>
            {/*NAVIGATION BAR*/}
            <FifaNavbar />
            {/*MAIN IMAGE AND TEXT*/}
            <TitleArea />
            {/*EACH YEAR'S WINNER CARDS*/}
            <WinnerCards />
            {/*Extra Space On The Bottom*/}
            <div style={{height: "400px"}}></div>
        </ApiProvider>
    )
}

export default Main

这是我的导航栏文件

import { useState } from "react";
import { Navbar, Nav, NavDropdown, Form, FormControl, Button, Container} from "react-bootstrap"
const FifaNavbar = ( {addCountry} ) => {
  const [country, setCountry] = useState(null)
  setTimeout(() => {
    document.getElementById("disabled").setAttribute("disabled", true)
  }, 0);
    return (
    <Navbar variant="dark" expand="md" className="navbar mb-5">
      <Container>
  <Navbar.Brand href="/">World Cup Winners</Navbar.Brand>
  <Navbar.Toggle aria-controls="basic-navbar-nav" />
  <Navbar.Collapse id="basic-navbar-nav">
    <Nav className="mr-auto">
      <Nav.Link href="#home">Countries</Nav.Link>
      <Nav.Link href="#link">Link</Nav.Link>
    </Nav>
    <Form inline>
    <Form.Group controlId="exampleForm.ControlSelect1" >
    <Form.Control as="select" onChange={e => setCountry(e.target.value)} >
    <option id="disabled">Search Countries</option>
      <option>Brazil</option>
      <option>Germany</option>
      <option>Italy</option>
      <option>Argentina</option>
      <option>France</option>
      <option>Uruguay</option>
      <option>England</option>
      <option>Spain</option>
      <option>Netherlands</option>
      <option>Czechoslovakia</option>
      <option>Hungary</option>
      <option>Sweden</option>
      <option>Croatia</option>
    </Form.Control>
  </Form.Group>
      <Button variant="outline-light" onClick={() => {addCountry({country})}} >Search</Button>
    </Form>
  </Navbar.Collapse>
  </Container>
</Navbar>
    )
}

export default FifaNavbar

当我按下导航栏中的按钮时我想要那个

<Button variant="outline-light" onClick={() => {addCountry({country})}} >Search</Button>

它将使用函数 addCountry() 将我所在州的国家/地区值发送到我的上下文 API,我可以在其中 console.log() it

感谢您的帮助

首先,您需要更改使用 Context 提供程序的方式,该提供程序除值外不获取任何其他道具。

<ContextApi.Provider value={{winnerData: api, setWinnerData: setApi, addCountry: addCountry}}>{props.children}</ContextApi.Provider>

那么你需要在你的导航栏组件中导入useContext:

import { ContextApi }  from "YOUR_CONTEXT_API_DIRECTORY";

const FifaNavbar = () => {
  const { addCountry } = React.useContext(ContextApi);
  //...
}