How to import components in React and edit them (Change their State)

Viewed 190

I'm trying to convert paragraph into inputs for users to edit their information. Basically when the user clicks a button the paragraphs become inputs. I would like to do this in a separate component if it's possible. This is what I have so far:

import React, { useState, useEffect } from "react";
import EditUser from "./EditUser";

const UserList = () => {
const [userApi, setUserApi] = useState([]);
const [getData, setGetData] = useState([]);

useEffect(() => {
fetch("http://user/api/getEndpoint")
  .then((getData) => getData.json())
  .then((json_result) => {
    setGetData(json_result.results);
    let userApi = showData(json_result.results);
    setUserApi(userApi);
  });
 }, []);

const showData = (getData) => {
return getData.map((item, key) => {
  return (
        <div className="body">
          <div key={key}>
            <img
              className="circle"
              src={item.picture.large}
              alt=""
            />
            <div className="list">
              <h5 className="title">
                {item.name.first} {item.name.last}
              </h5>
              <p className="text">{item.email}</p>
              <p className="text">{item.phone}</p>
              <p className="text">
                {item.location.city}, {item.location.state}
              </p>
            </div>
            <hr />
            <div>
              <EditUser /> //Import other component as a button 
                             to edit changes for the paragraphs above.
            </div>
          </div>
        </div>
        );
      });
     };

export default UserList;

And be able to edit the paragraph on this component:

import React, { useState, useEffect } from "react";

function EditUser() {

const [user, editUser] = useState([]);

 return (
   <div>
     <button
       className="button"
       onClick={() => editUser([])} //Convert paragraph from 
                                      userList to inputs for editing. 
     >
     Edit User
     </button>
   </div>
 );
}

 export default EditUser;

Thanks for the help!

1 Answers

As much as I understand ur question, you can do something like this https://codesandbox.io/s/happy-swartz-ikqdn?file=/src/clickInput.js


  • You can have a items and setItems state and functions in the parent component.
  • You can do to save the value of a function is

function changeItem(i, value) { //index to be updated and value
  let newItems = [...items];
  newItems[i] = value;
  setItems(newItems);
}

  • There will a component to map over and render the list

function List({ items, setItem }) {
  return (
    <>
      {items?.map((itm, i) => (
        <Label
          key={i}
          title={itm}
          onChange={(e) => setItem(i, e.target.value)} //pass the index and value of the edited index to be saved
        />
      ))}
    </>
  );
}

  • For each label, you can create a component having an edit state, which is triggered when clicked.

function Label({ title, onChange }) {
  const [edit, setEdit] = useState(false);

  return (
    <div>
      {!edit ? (
        <span onClick={() => setEdit(true)}>{title}</span> //onclick to start edit
      ) : (
        <>
          <input autoFocus value={title} onChange={onChange} /> //input to edit
          <button onClick={() => setEdit(false)}>Save</button> //this is to toggle edit
        </>
      )}
    </div>
  );
}
Related