简体   繁体   中英

How to correctly pass a callback and a state to the Layout element in React Router Dom?

How to correctly pass callbacks and states to the Layout so that they can be used elsewhere? When I share this as below, I have errors and a white screen:

class Menu extends Component {
  constructor(props) {
    super(props);
    this.onSearchF = this.onSearchF.bind(this)
  } 
  state = {
    searchBlock: false,
  };

  onSearchF = (keyword) => {
    const filtered = this.state.data.filter((entry) =>
      Object.values(entry).some(
        (val) => typeof val === "string" && val.toLowerCase().includes(keyword.toLowerCase())
      )
    );
  };
  render() {
    return (
      <div className="content">
        <Routes>
          <Route path="/" element={<Layout searchBlock={this.state.searchBlock} onSearch={()=>this.onSearchF()}/>}>
            <Route
              index
              element={
                <Home data={this.state.data} num={this.state.data.length} />
              }
            />
          </Route>
        </Routes>
      </div>
    );
  }
}
export default Menu;

Here I pass the callback to the Header that I previously passed to the Layout :

const Layout = () => {
  return (
    <>
      <Header sblock={this.props.searchBlock} onS = {this.props.onSearch}/>  
    </>
  );
};
export default Layout;

I want to use the callback here:

function Header() {
  return (
    <header className="header">
        <button onClick={()=>console.log(this.props.sblock)}>button</button>
    </header>
  );
}

export default Header;

Your Layout is a functional component, and you are trying to use this.props in it; this is incorrect. Get the props as part of arguments instead, like so:

import { Outlet } from "react-router-dom";
const Layout = ({searchBlock,onSearch}) => {
  return (
    <>
      <Header sblock={searchBlock} onS={onSearch}/>  
      <Outlet/>
    </>
  );
};
export default Layout;

Issues

  • The Layout component isn't accepting any props.
  • The Layout component isn't rendering an Outlet for nested routes.

Solution

It seems that Layout only exists to render the Header component. I'd suggest rendering Header directly in the Main component.

Example:

class Menu extends Component {
  state = {
    data: [],
    searchBlock: false,
  };

  onSearch = (keyword) => {
    const filtered = this.state.data.filter((entry) =>
      Object.values(entry).some((val) => 
        typeof val === "string"
        && val.toLowerCase().includes(keyword.toLowerCase())
      )
    );

    ... do something with filtered ...
  };

  render() {
    const { data, searchBlock } = this.state;

    return (
      <div className="content">
        <Header sblock={searchBlock} onS={this.onSearch} />
        <Routes>
          <Route
            path="/"
            element={<Home data={data} num={data.length} />}
          />
        </Routes>
      </div>
    );
  }
}

export default Menu;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM