问题
I have a form with two columns. The left column is a proposed value for the right column. I currently present both values from separate API calls. This is working.
This is the current code:
const dbContact = useDbContact(contact.Group);
This sets the value of the current values, contact.Group
from the proposed values being passed to the API call.
I then later use this to call the form input value:
<Form.Row>
<Form.Group as={Col} controlId="currentSecName" className="mb-2">
<Form.Control type="input" name="1secname" value={contact.SecretaryName} readOnly />
</Form.Group>
<Form.Group as={Col} controlId="dbSecName" className="mb-2">
<Form.Control type="input" name="2secname" value={dbContact.SecretaryName} readOnly />
</Form.Group>
<Button className="PrimaryButton" size="sm">
Accept proposed
</Button>
<div class="divider" />
</Form.Row>
Now I have all this working, my next step was to make the 'accept' button update the current value with the proposed. My code being something like this:
const dbContact = useDbContact(contact.Group);
const [dbSecName, setDbSecName] = useState(dbContact.SecretaryName)
and
<Form.Control type="input" name="2secname" value={dbSecName} readOnly />
which would allow me to change the state value 'onClick'
When I do this though, I get a 'dbContact.SecretaryName is undefined'. Now, I'm assuming that considering I asked for the value in the form directly, during testing, I was lucky that the value was populated before being asked for so there's potentially something wrong with the API call.
Here is the API call:
async function getData(group) {
try {
const apiGroups = await API.graphql(graphqlOperation(queries.getNtig, { PK: "Group#" + group, SK: "Officers#2" }));
let listItem = await apiGroups.data.getNTIG;
let PK = await apiGroups.data.getNTIG.PK.split("#")[1];
let secJson = await JSON.parse(apiGroups.data.getNTIG.Secretary);
let id = 1;
let receivedItems = {
Id: id,
PK: PK,
SecretaryName: secJson.Name,
};
setList(receivedItems);
} catch (err) {}
}
useEffect(() => {
if (!isAuthenticated) {
return;
}
getData(group);
}, [isAuthenticated, group]);
console.log(list);
return list;
}
What I'm hoping someone can help me with is either correcting the logic so the setting the state value works, or an alternative to changing the form input value.
回答1:
I'm not sure if this is the correct way to do this, but it works and it also resolves an additional problem of changing an uncontrolled element, when the element is re-rendered, when the state value changes from the API call.
This is where I get the values from the API call and initally setState:
const dbContact = useDbContact(contact.Group);
const [dbSecName, setDbSecName] = useState("");
I then use useEffect with an async function to wait for the value from the API call and setState using that value:
useEffect(() => {
async function getDbContact() {
let secName = await dbContact.SecretaryName;
setDbSecName(secName);
}
getDbContact();
}, [dbContact.SecretaryName]);
I can then use the value in the form input:
<Form.Control type="input" name="2secname" value={dbSecName || ""} readOnly />
Obviously I need to handle the state change in the form input but that should now be straight forward.
I'm no developer so if a better answer comes along I'd be pleased to see it. For now, I seem to have resolved my own problem.
来源:https://stackoverflow.com/questions/65233570/react-using-state-to-update-values-or-not