mirkovski
mirkovski

Reputation: 75

How to pass props to another component in React?

so I have a table component with a search filter onPressEnter in the first column and I want my searchBar component to do the same thing basically.

Here in my table.js I want to pass confirm() to Searchbar.js

const columns = [
    {
      key: "1",
      title: "Title",
      dataIndex: "title",
      render: (text) => <a href="/">{text}</a>,
      sorter: (record1, record2) => record1.title.localeCompare(record2.title),
      filterDropdown: ({ setSelectedKeys, selectedKeys, confirm }) => {
        return (
          <Input
            autoFocus
            placeholder="Search Column..."
            value={selectedKeys[0]}
            onChange={(e) => {
              setSelectedKeys(e.target.value ? [e.target.value] : []);
            }}
            onPressEnter={() => {
              confirm();
            }}
            onBlur={() => {
              confirm();
            }}
          ></Input>
        );
      },
      filterIcon: () => {
        return <SearchOutlined />;
      },
      onFilter: (value, record) => {
        return record.title.toLowerCase().includes(value.toLowerCase());
      }
    },]

Here's my Searchbar.js

function Searchbar() {
  return (
    <div>
      <Form className="d-flex align-items-start">
        <Form.Control
          type="search"
          placeholder="Enter a keyword or a company name..."
        />
        <Button>Search</Button>
      </Form>
    </div>
  );
}

export default Searchbar;

I've also made a codesandbox project to better visualize my issue. So I have a main searchbar component and I want it to do the same thing as the search filter in my table component. Is that possible? If so, what is the best way to approach this? I appreciate any help. Thank you!

Upvotes: 1

Views: 5306

Answers (2)

Kieran Quinn
Kieran Quinn

Reputation: 1115

I would recommend a refactor. Move your data and search logic up a level to the parent and pass as props to the child components, like this:

import React, { useState, useEffect } from "react";
import Searchbar from "../components/Searchbar";
import MyTable from "../components/Table";

export default function HomeAfterSearch() {
  const [data, setData] = useState([]);
  const [searchText, setSearchText] = useState("");
  const [loading, setLoading] = useState(true);

  const getData = () => {
    fetch("https://jsonplaceholder.typicode.com/todos")
      .then((response) => response.json())
      .then((data) => {
        setData(data);
      })
      .catch((err) => {
        console.log(err);
      })
      .finally(() => {
        setLoading(false);
      });
  };

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

  return (
    <div className="App">
      <Searchbar searchText={searchText} setSearchText={setSearchText} />
      <MyTable
        searchText={searchText}
        setSearchText={setSearchText}
        data={data.filter((item) => {
          if (!searchText) return true;
          else if (
            JSON.stringify(item)
              .toLowerCase()
              .includes(searchText.toLowerCase())
          )
            return true;
          else return false;
        })}
      />
    </div>
  );
}

So then in MyTable you would declare it like this:

function MyTable(props) {
const { data, loading } = props;
.....

And SearchBar like this:

function Searchbar(props) {
const { searchText, setSearchText } = props;

Upvotes: 1

Sarah
Sarah

Reputation: 72

Make your SearchBar as a React.Component, then you can use props to pass data or function from its parent component.

  1. You can do it as belows:
import React, {Component} from "react";
import { Form, Button } from "react-bootstrap";

// change the SearchBar to Component
class Searchbar extends Component{
  constructor(props){
    // then you can use props to pass data 
    // or function from its parent component
  }

  render(){
    return (
      <div>
        <Form className="d-flex align-items-start">
          <Form.Control
            type="search"
            placeholder="Enter a keyword or a company name..."
          />
          <Button>Search</Button>
        </Form>
      </div>
    );
  }
}

export default Searchbar;
  1. You can also do it in an simple way:
function Searchbar(props) {
  // use props to pass data from parent component
  return (
    <div>
      <Form className="d-flex align-items-start">
        <Form.Control
          type="search"
          placeholder="Enter a keyword or a company name..."
        />
        <Button>Search</Button>
      </Form>
    </div>
  );
}

export default Searchbar;

You can find more information about Custom Component and props from Official Document.

If you use TypeScript, you can define an IProps interface:

interface IProps{
  data: number,
  onConfirm(): void
}

When using SearchBar, do like this:

<SearchBar
    data = 1,
    onConform={() =>{
        // do something, when calling onConrfim() function
    }}>
</SearchBar>

Upvotes: 0

Related Questions