Reputation:
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?.
Upvotes: 2
Views: 1284
Reputation: 16122
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>
Upvotes: 1