【问题标题】:How to assign value onClick from different component to another component in React如何将值 onClick 从不同组件分配给 React 中的另一个组件
【发布时间】:2020-06-19 15:04:44
【问题描述】:

我想做什么:

  • 当我点击我的按钮时,即Navbar.js 中的Search,我想在变量urlQuery 中分配搜索文本,这样我就可以在Episodes.js 组件中将其作为道具传递
  • 最终目标是将 urlQuery 从 Navbar.js 以某种方式传递给 Episodes.js 组件,以便我可以查询 REST api

我如何实现所需的行为请帮助

App.js

import React, { useState } from 'react';
import './App.css'
import Episodes from './components/Episodes/Episodes'
import CustomNavbar from './components/Navbar/Navbar'
import Pagination from './components/Pagination/Pagination'
function App() {

  const [postsPerPage] = useState(20);
  const [currentPage, setCurrentPage] = useState(1);

  const url=`https://rickandmortyapi.com/api/episode?page=${currentPage}`
  let urlQuery = `https://rickandmortyapi.com/api/episode?name=${SEARCH TEXT HERE}`

  const paginate = pageNumber => setCurrentPage(pageNumber);

  return (
    <div>
      <CustomNavbar />
      <Episodes
      urlQuery={urlQuery}
      url={url}
      />
      <Pagination
        postsPerPage={postsPerPage}
        totalPosts={36}
        paginate={paginate}
      />
    </div>
  );
}

export default App;

Navbar.js

import React from 'react';
import Navbar from 'react-bootstrap/Navbar';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import FormControl from 'react-bootstrap/FormControl';

const customNavbar = () => {

  return (
    <Navbar bg="light" expand="lg">
      <Navbar.Brand href="#home">Rick And Morty</Navbar.Brand>
      <Form inline>
        <FormControl type="text" placeholder="Search" />
        <Button>Search</Button>
      </Form>
    </Navbar>
  );
}
export default customNavbar

编辑

根据 Zohaib 的建议,抛出此错误

Failed to compile.

./src/components/Navbar/Navbar.js
  Line 14:48:  Unexpected use of 'event'  no-restricted-globals

Search for the keywords to learn more about each error.   

【问题讨论】:

  • 您通过 URL 传递数据是否有特定原因?直接从子组件到父组件的通信是否适用于您的用例?
  • 你能用外行的话问一下吗?没看懂问题
  • 如果网址不变,可以吗?
  • 不,它必须改变......
  • 糟糕,我误读了这个问题。我的意思是浏览器的 URL,但这无关紧要。给我一分钟,我会试着回答这个问题

标签: javascript reactjs react-hooks


【解决方案1】:

App.js

import React, { useState, useEffect } from 'react';
import './App.css'
import Episodes from './components/Episodes/Episodes'
import CustomNavbar from './components/Navbar/Navbar'
import Pagination from './components/Pagination/Pagination'
function App() {

  const [postsPerPage] = useState(20);
  const [currentPage, setCurrentPage] = useState(1);
  const [userSearchValue, setUserSearchValue] = useState('');

  const [url, setUrl] = useState(``);
  const [urlQuery, setUrlQuery] = useState(``)

  useEffect(() => {
    setUrl(`https://rickandmortyapi.com/api/episode?page=${currentPage}`)
  }, [currentPage]);

  useEffect(() => {
    setUrlQuery(`https://rickandmortyapi.com/api/episode?name=${userSearchValue}`)
  }, [userSearchValue])

  const paginate = pageNumber => setCurrentPage(pageNumber);

  const handleButtonClick = (searchValue) => {
      setUserSearchValue(searchValue);
  }

  return (
    <div>
      <CustomNavbar
      onButtonClick={handleButtonClick}
      />
      <Episodes
      urlQuery={urlQuery}
      url={url}
      />
      <Pagination
        postsPerPage={postsPerPage}
        totalPosts={36}
        paginate={paginate}
      />
    </div>
  );
}

export default App;

Navbar.js

import React, { useState } from 'react';
import Navbar from 'react-bootstrap/Navbar';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import FormControl from 'react-bootstrap/FormControl';

const customNavbar = ({ onButtonClick }) => {

    const [searchValue, setSearchValue] = useState('');

  return (
    <Navbar bg="light" expand="lg">
      <Navbar.Brand href="#home">Rick And Morty</Navbar.Brand>
      <Form inline>
        <FormControl type="text" placeholder="Search" value={searchValue} onChange={(e) => setSearchValue(e.target.value)} />
        <Button onClick={() => onButtonClick(searchValue)}>Search</Button>
      </Form>
    </Navbar>
  );
}
export default customNavbar

这里的重要部分是将handleButtonClick 函数传递给子组件(导航栏)。这样,您可以随时在子组件中调用该父函数(即,当用户单击提交按钮时)。

【讨论】:

  • 这个错误React Hook "useState" is called in function "customNavbar" which is neither a React function component or a custom React Hook function
  • nvm 通过 Capitolizing CustomNavbar 修复了它
  • 另外e is not defined error 并使其事件也会引发错误
  • 打错字了(更新了帖子) - 尝试将行更改为:&lt;FormControl type="text" placeholder="Search" value={searchValue} onChange={(e) =&gt; setSearchValue(e.target.value)} /&gt;
【解决方案2】:

你的意思是像this这样的东西吗?

【讨论】:

  • 仅链接的答案不值得投票。如果页面挂了怎么办?如果页面发生变化怎么办?请从外部页面拉取相关代码并添加说明。
  • 这应该是评论,而不是答案
  • @3limin4t0r 这个问题不值得长,所以答案是!
【解决方案3】:

有一个关于这个特定问题的 React 指南:Lifting State Up

通常您所做的是管理父级中的状态。在这种情况下App 管理搜索文本状态。您将函数传递给组件以更改此状态。依赖此状态的组件通过属性传递值。

这是一个例子:

const {useEffect, useState} = React;

function App() {
  const episodesURL = "https://rickandmortyapi.com/api/episode";
  
  const [page, setPage] = useState(1);
  const [pageInfo, setPageInfo] = useState({});
  const [searchText, setSearchText] = useState("");
  const [episodes, setEpisodes] = useState([]);
  
  useEffect(() => {
    const url = new URL(episodesURL);
    url.searchParams.set("page", page);
    if (searchText) url.searchParams.set("name", searchText);
    
    fetch(url)
    .then(response => response.json())
    .then(response => {
      if (response.error) {
        setPageInfo({});
        setEpisodes([]);
      } else {
        setPageInfo(response.info);
        setEpisodes(response.results);
      }
    });
  }, [page, searchText]);

  const search = searchText => {
    setSearchText(searchText);
    setPage(1);
  };
  
  return (
    <div>
      <CustomNavbar search={search} />
      <Episodes episodes={episodes} />
      <Pagination setPage={setPage} info={pageInfo} />
    </div>
  );
}

function CustomNavbar({search}) {
  const [searchText, setSearchText] = useState("");
  
  const handleFormSubmit = event => {
    event.preventDefault();
    search(searchText);
  };
  
  return (
    <form onSubmit={handleFormSubmit}>
      <input
        type="text"
        placeholder="search"
        value={searchText}
        onChange={event => setSearchText(event.target.value)}
      />
      <button type="submit">Search</button>
    </form>
  );
}

function Episodes({episodes}) {  
  return (
    <table>
      <thead>
        <tr>
          <th>episode</th>
          <th>name</th>
          <th>air date</th>
        </tr>
      </thead>
      <tbody>
        {episodes.map(episode => (
          <tr key={episode.id}>
            <td>{episode.episode}</td>
            <td>{episode.name}</td>
            <td>{episode.air_date}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function Pagination({setPage, info}) {
  return (
    <div>
      {info.prev && <a onClick={() => setPage(page => page - 1)}>previous</a>}
      {info.next && <a onClick={() => setPage(page => page + 1)}>next</a>}
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
th { text-align: left; }
a { cursor: pointer; }
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

【讨论】:

    【解决方案4】:

    将 urlQuery 更改为状态变量。然后,将 setUrlQuery 作为 prop 传递给 NavBar,并在搜索按钮 clickEvent 上调用 setUrlQuery 函数。

    【讨论】:

    • &lt;Button onClick={props.setUrlQuery(event.target.value)}&gt;Search&lt;/Button&gt; 喜欢这个?如果是,则抛出错误
    • onClick={()=>props.setUrlQuery(event.target.value)} 检查这个或显示错误
    • 实际上错误在于事件。尝试先传递硬编码值。
    • 检查此链接以获取值并将其传递给函数stackoverflow.com/questions/45194498/…
    • 那是基于类的组件
    猜你喜欢
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 2019-02-24
    • 2017-06-12
    • 2018-05-07
    • 2023-01-07
    相关资源
    最近更新 更多