Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass this.props.children using hooks in react

this is my first time to create a react application.

I wanted to pass buttons from index.js to table component that uses hooks.

Declaration:

  const testButton = () => {
    return (
      <React.Fragment>
        <button>Test1</button>
        <button>Test2</button>
        <button>Test3</button>
        <button>Test4</button>
        <button>Test5</button>
      </React.Fragment>
    );
  };

pass it to Table component

 return (
    <React.Fragment>
      <TestTable
        {...{
          testButton}} />
    </React.Fragment>

Then, table component will use it to render the table, with the buttons included.

export default function TestTable({
testButton,
  ...props
}) 

return (
{testButton});

Am I doing it correctly?

How can I export this from index.js, import in Table component.js, and render in Table component?

Thank you.

like image 669
Dan Avatar asked May 23 '19 10:05

Dan


3 Answers

I think what you want is:

const TestTable = ({ children }) => {
  return (
    <table>
      <tr>
        <td>Something...</td>
        <td>{children}</td>
      </tr>
    </table>
  )
}

And then:

const App = () => {
  return (
    <TestTable>
      <button>Test 1</button>
      <button>Test 2</button>
      <button>Test 3</button>
    </TestTable>
  )
}

Hope it helps!

like image 58
Jorge del Rio Avatar answered Nov 12 '22 14:11

Jorge del Rio


The React library promotes component composition. For a good recent writeup of this pattern read Robin Wieruchs article

You can refactor your TestTable component like the following:

Here I have added a codesandbox example: https://codesandbox.io/embed/smoosh-cache-ytfky

import React from 'react'

export default function TestTable(props) {
  return (
    <React.Fragment>
      {props.children}
    </React.Fragment>
  )  
}

Your TestButton component can remain mostly the same. You need to add the export keyword to the beginning of the component. Actually, the components are just plain old functions. To learn more about the different styles of exporting functions see Alex Rauschmayer great description. there are arguments for using either default exports or named exports, I personally prefer named exports which is more declarative and just easier for me to see what is happening.

  export default function TestButton() {
    return (
      <React.Fragment>
        <button>Test1</button>
        <button>Test2</button>
        <button>Test3</button>
        <button>Test4</button>
        <button>Test5</button>
      </React.Fragment>
    );
  };

You can now compose your two components in another function as follows:

export function DisplayTable(props) {
  return (
    <TestTable>
       <TestButton />
    </TestTable>
)
}

NOTE:

  1. This assumes all your functions are in one file, but it is better to put them in their own file and import / export them.
  2. The this keyword is only applicable if you are writing a class component, if you write a function component then all you get is props, but you have to explicitly declare it in your function arguments.
  3. I have converted all your ES6 arrow functions into regular javascript functions, I find it is easier to conceptualise, and learn these are just regular functions, but in React land they are your components.

As for React Hooks, they are a new introduction to React since 16.8 which really solve a specific use case of being able to handle state and side effects without using classes. see the original docs for a great description

like image 32
Faktor 10 Avatar answered Nov 12 '22 15:11

Faktor 10


In your index.js (where you return the buttons):

const TestButtons = () => (
  <>
    <button>Test1</button>
    <button>Test2</button>
    <button>Test3</button>
    <button>Test4</button>
    <button>Test5</button>
  </>
)

export default TestButtons

Then, in your table.js:

import TestButtons from 'path/to/index.js'

const TestTable = () => (
  <TestButtons />
)

You should use the import statement to import a component from another file.

like image 26
Kobe Avatar answered Nov 12 '22 13:11

Kobe