Home > front end >  ReactJS functions outside of component
ReactJS functions outside of component

Time:11-25

Just had an interview in ReactJS, I was given a strange template in which some functions (question1(), question2(), question3()) are outside of the components

I was asked to print the names and add a button to add new object to data, then the screen would update with new name

1. Let say if I only allowed to change the return values of question1(), question2(). question3(), is it possible to pass 'setName' to question1(), question2(), question3()?

2. Move those functions (question1(), question2(), question3()) inside the App component is it the only way to complete it?

import React from "react";
import "./styles.css";

function question1() {
  return "---";
}
function question2() {
  return "---";
}
function question3() {
  return "---";
}

export default function App() {

const [name, setName] = useState();

  const data = [
    {
      name: "Ruby",
      stars: 10,
      popularity: "90%"
    },
    {
      name: "Elliot",
      stars: 90,
      popularity: "100%"
    },
    {
      name: "Holly",
      stars: 55,
      popularity: "15%"
    },
    {
      name: "Jack",
      stars: 50,
      popularity: "1%"
    },
    {
      name: "",
      stars: 0,
      popularity: ""
    }
  ];

  return (
    <div className="App">
      <h2>Code the answers below!</h2>
      <p>
        Question 1:
        <br />
      </p>
      {question1(data)}
      <br />
      <br />
      <p>
        Question 2:
        <br />
      </p>
      {question2(data)}
      <br />
      <br />
      <p>
        Question 3:
        <br />
      </p>
      {question3(data)}
      <br />
      <br />
      <p>
        Question 4:
        <br />
      </p>
      <button>Add another entry</button>
      <br />
      <br />
    </div>
  );
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I'm not sure what the question is.

Do you mean something like this?

function question1(setter, data) {
  setter(data[0].name);
  return data[0].name;
}
...
{question1(setName, data)}

This would not work because every time it renders, it will try to call question1(...) which will call setName(...) resulting in a infinite loop of render. This will be caught by react and it will break. This will occur regardless if the function is in the App function scope or outside.

It it not recommended/bad practice to use functions as elements, especially if the function is triggering hooks that causes re-renders.

Edit:

If you mean that the functions question1(), 2, 3 are returning some static data and not calling any async hooks that triggers re-rendering. Then it should work if regardless if it's inside or outside the App function scope. Although it's recommended to put it inside so that it's more encapsulated.

CodePudding user response:

I guess I distracted by the question template, this is the answer

import React, {useState} from "react";
import "./styles.css";

function question1(data) {
let result = '';
  
data.forEach((element, index, array) => {
    result  = element.name;
  
  })

  return result;
}
function question2(data, setData) {

  setData(   [...data, {
    name: "Ruby",
    stars: 10,
    popularity: "90%"
  }]);
  return "---";
}



function question3() {
  return "---";
}

export default function App() {

  const [data, setData] = useState([
    {
      name: "Ruby",
      stars: 10,
      popularity: "90%"
    },
    {
      name: "Elliot",
      stars: 90,
      popularity: "100%"
    },
    {
      name: "Holly",
      stars: 55,
      popularity: "15%"
    },
    {
      name: "Jack",
      stars: 50,
      popularity: "1%"
    },
    {
      name: "",
      stars: 0,
      popularity: ""
    }
  ]);



  return (
    <div className="App">
      <h2>Code the answers below!</h2>
      <p>
        Question 1:
        <br />
      </p>
      {

question1(data)
      }
      <br />
      <br />
      <p>
        Question 2:
        <br />
      </p>
      
      <br />
      <br />
      <p>
        Question 3:
        <br />
      </p>
      {question3(data)}
      <br />
      <br />
      <p>
        Question 4:
        <br />
      </p>
      <button onClick={() => question2(data, setData)} >Add another entry</button>
      <br />
      <br />
    </div>
  );
}
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I'm sure that template is good for something but it's useless for the requirements that you've been set. Which were:

  1. List the names from each object in the data array
  2. Have a button that adds a new object to the array

Here's how I would approach it. Note I'm passing in the data as a prop to the component for convenience, and I've added a form with three inputs so you can add the information you want.

const { useState } = React;

function Example({ input }) {

  // Set two states. The first holds the data.
  // The second holds an object that is updated
  // when the input values change
  const [ data, setData ] = useState(input);
  const [ newUser, setNewUser ] = useState({});

  // If an input value changes update the
  // newUser object using the name and the value
  function handleChange(e) {
    const { name, value } = e.target;
    setNewUser({ ...newUser, [name]: value });
  }

  // When the button is clicked update
  // the data state with object stored in
  // the `newUser` state
  function handleClick() {
    const updated = [ ...data, newUser ];
    setData(updated);
  }

  // `map` over the data and display each name
  return (
    <div>
      {data.map(obj => {
        return <div>{obj.name}</div>;
      })}
      <form onChange={handleChange}>
        Name: <input type="text" name="name" value={newUser.name} /><br />
        Stars: <input type="text" name="stars"  value={newUser.stars} /><br />
        Popularity: <input type="text" name="popularity"  value={newUser.popularity} /><br />
        <button type="button" onClick={handleClick}>Add new person</button>
      </form>
    </div>
  );
};

const data=[{name:"Ruby",stars:10,popularity:"90%"},{name:"Elliot",stars:90,popularity:"100%"},{name:"Holly",stars:55,popularity:"15%"},{name:"Jack",stars:50,popularity:"1%"},{name:"",stars:0,popularity:""}];

ReactDOM.render(
  <Example input={data} />,
  document.getElementById('react')
);
form, button { margin-top: 1em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related