0

how do I get the values from the component that has the input to the component that is actually going to make the post? is that posible? or should I put all in the same component? this is my Item component:

import React, {useState} from 'react';
import {Col} from 'reactstrap';

export function CustomFieldsItem({item}) {
  const [value, setValue] = useState(false);

  function handleChange(e) {
    setValue(e.target.value);
  }

  return (
    <>
      <li className={'list-group-item d-flex border-0'} key={item.id}>
        <Col md={2}>
          <label>{item.label}</label>
        </Col>
        <Col md={10}>
          <input className="form-control" type="text" value={value || item.value} onChange={handleChange} />
 // <-- this is the value I want to pass to my update component when I type on it
// but the save button is in the "update component" (the one under)

        </Col> 
      </li>

    </>
  );
 }

This is my update Component:

import React, {useState, useEffect} from 'react';
import axios from 'axios';
import {post} from '../../common/fetch/fetchOptions';

export function CustomFieldsUpdate({item}) {
  const [value, setValue] = useState(false);

  const updateCustomField = async ({data}) => {
    try {
      await axios(
        post({
          url:'http://localhost:9000/projectcustomfields.json/update/1741?id=party&value=newvalue',

// <-- I want to set the value here, instead of "newvalue" but right now Im happy with just a log of the value from the component above in the console when I click on "Save" button.
// When I save right now I just post hardcoded values (which is what I want to change)

          data: data,
          method: 'POST',
          mode: 'cors',
          withCredentials: true,
          credentials: 'include',
        }),

       );
      console.log(value);
    } catch (e) {
      console.log('Error when updating values: ', e);
    }
  };

  return (
    <div className={'d-flex justify-content-end mr-4'}>
      <button
        type={'button'}
        className={'btn btn-primary mr-2'}
        onClick={updateCustomField}
      >
        Save
      </button>
    </div>
  );
}

I have another component that list the objects the I want to update, maybe I need to pass the values from this component, maybe can use that?

import React, {useState, useEffect} from 'react';
import {CustomFieldsList} from './customFieldsList';
import {toast} from 'react-toastify';
import {ToastInnerDisplay} from '@learnifier/jslib-utils';
import {CustomFieldsItem} from './customFieldsItem';

export function CustomFieldsContainer({match}) {
  const [value, setValue] = useState({
    data: null,
    loading: true,
    error: null,
  });

  /**
   * Initial loading of data.
   */
   async function fetchData() {
     setValue({...value, error: null, loading: true});
    try {
      let url = `http://localhost:9000/projectcustomfields.json/list/1741`;
      const res = await fetch(url, {
        method: 'POST',
        mode: 'cors',
        withCredentials: true,
        credentials: 'include',
      });
      let data = await res.json();
      setValue(prevValue => ({...prevValue, data: data.customFields, loading: false}));
    } catch (error) {
      toast.error(<ToastInnerDisplay message={error.message} />);
      setValue({...value, error, loading: false});
    }
  }

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

  if (value.loading) {
    return <div>loading...</div>;
  } else if (value.error) {
    return <div>ERROR</div>;
  } else {
    return (
      <div className={'section-component'}>
        <div className={'col-md-6 col-sm-12'}>
          <h2>Custom Fields</h2>
          <CustomFieldsList setValue={setValue} list={value.data} />
        </div>
      </div>
    );
    // return <ChildComponent data={value.data} />
  }
}

I render the components with a component list:

import React from 'react';
import {CustomFieldsItem} from './customFieldsItem';
import {CustomFieldsUpdate} from './customFieldsUpdate';

export function CustomFieldsList({list, setValue, update, 
updateCustomField}) {
  console.log(list);
console.log(update);
  return (
    <>
      <form>
        <ul className={'list-group border-0'}>
          {list.map(item => (
            <CustomFieldsItem item={item} key={item.id} />
          ))}
        </ul>
        <CustomFieldsUpdate updateCustomField={updateCustomField} setValue={setValue}/>
       </form>
    </>
  );
}
Fernando Löpez
  • 61
  • 2
  • 11
  • How are each components rendered? – Shubham Khatri May 03 '20 at 16:02
  • I updated my question with the component that renders all other components at the bottom :) @ShubhamKhatri – Fernando Löpez May 03 '20 at 16:09
  • 1
    @FernandoLöpez You can move the state to the parent component, `CustomFieldsList` and then create a function in `CustomFieldsItem` that update the parent components state. This is done as shown in [this question](https://stackoverflow.com/questions/35537229/how-to-update-parents-state-in-react) – Ibraheem Ahmed May 03 '20 at 17:08
  • mmm I did try a lot from the examples in the answered question you sent but im having a real hard time converting from class component to function components and using hooks – Fernando Löpez May 04 '20 at 05:51

0 Answers0