2

I am trying to watch a field which have watch:true field.In other words I want add useEffect dynamically.I have one json (which is coming from server).I want to watch field value (which have property watch:true).using it's value I want to update other field value .

here is my code

https://codesandbox.io/s/crimson-violet-uxbzd

see this object have watch: true, so I need to watch or check if it value is changed or not

 {
     label: "First",
     name: "first",
     type: "select",
     remove: true,
     watch: true,
     options: ["", "one", "two"]
},

if it's value is changed then call this function

const getSecondDropdownValue = function(value) {
    return new Promise((resolve, reject) => {
      if (value === "one") {
        setTimeout(function() {
          resolve(["three", "four"]);
        }, 1000);
      }

      if (value === "two") {
        setTimeout(function() {
          resolve(["five", "six"]);
        }, 1000);
      }
    });
  };

any update?.

3
  • how do you render the fields? Commented Feb 17, 2020 at 15:18
  • using map function see my code sandbox link Commented Feb 17, 2020 at 15:20
  • @JuniusL. can you please help me Commented Feb 17, 2020 at 15:22

1 Answer 1

1

Check if the item has watch property, if it does pass getSecondDropdownValue to onChange event of the select option. something like

<select onChange={hasWatch ? getSecondDropdownValue : () => {}}>...</select>

Create a component that will render select options.

// options = array of list options
// onChange = onchange event handler
// name = name of the select
const Option = ({ options, onChange, name }) =>
  (options.length && (
    <select onChange={(e) => onChange(e.target.value, name)}>
      {Array.isArray(options) &&
        options.map((option, index) => (
          <option value={option} key={option + index}>{option}</option>
        ))}
    </select>
  )) ||
  false;

Add useState for storing the data from the api.

// initial data from the api
const [data, updateData] = useState(apiData);

// update select options and the list
const updateSelectData = (list, updated) => {

    const index = list.findIndex(item => item.name === updated.name);
    return [
      ...list.slice(0, index),
      Object.assign({}, list[index], updated),
      ...list.slice(index + 1)
    ];
  };

getSecondDropdownValue function

const getSecondDropdownValue = function(value, name) {
  const updated = data.find(
    item => item.dependentField && item.dependentField[0] === name
  );

  // return new Promise((resolve, reject) => {
  if (value === "one") {
    // setTimeout(function() {
    // resolve(["three", "four"]);
    // }, 1000);
    updated.options = ["three", "four"];
  }

  if (value === "two") {
    // setTimeout(function() {
    // resolve(["five", "six"]);
    // }, 1000);
    updated.options = ["five", "six"];
  }
  // });

  updateData(updateSelectData(data, updated));
};

Example

// Get a hook function
const {useState} = React;

const apiData = [
    {
      label: "First",
      name: "first",
      type: "select",
      watch: true,
      options: ["", "one", "two"]
    },
    {
      label: "Second",
      name: "second",
      options: [],
      dependentField: ["first"],
      type: "select"
    }
  ];
  
// option component  
const Option = ({ options, onChange, name }) =>
  (options.length && (
    <select onChange={(e) => onChange(e.target.value, name)}>
      {Array.isArray(options) &&
        options.map((option, index) => (
          <option value={option} key={option + index}>{option}</option>
        ))}
    </select>
  )) ||
  false;

function App() {

  const [data, updateData] = useState(apiData);

  const updateSelectData = (list, updated) => {
    const index = list.findIndex(item => item.name === updated.name);
    return [
      ...list.slice(0, index),
      Object.assign({}, list[index], updated),
      ...list.slice(index + 1)
    ];
  };

  const getSecondDropdownValue = function(value, name) {
    const updated = data.find(
      item => item.dependentField && item.dependentField[0] === name
    );

    // return new Promise((resolve, reject) => {
    if (value === "one") {
      // setTimeout(function() {
      // resolve(["three", "four"]);
      // }, 1000);
      updated.options = ["three", "four"];
    }

    if (value === "two") {
      // setTimeout(function() {
      // resolve(["five", "six"]);
      // }, 1000);
      updated.options = ["five", "six"];
    }
    // });

    updateData(updateSelectData(data, updated));
  };

  return (
    <div className="App">
      {data.map((options, index) => (
        <Option
          name={options.name}
          key={index}
          onChange={options.watch ? getSecondDropdownValue : () => {}}
          options={options.options}
        />
      ))}
    </div>
  );
}
// Render it
ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.