问题
I need to use a fetch inside the FormDataConsumer tag but it seems FormDataConsumer does not support async functions. This code didn't work for me:
<FormDataConsumer>
{
async ({ formData, scopedFormData, getSource, ...rest }) => {
return await fetch('/api/v1/attributes/'+scopedFormData.single_attributes_label)
.then(res => res.json())
.then(data => {
console.log(JSON.stringify(data));
//return JSON.stringify(data);
resolve(JSON.stringify(data));
});
return JSON.stringify(scopedFormData);
}
}
</FormDataConsumer>
I also checked this code and this one also didn't work:
async function getAttrItem(id) {
return await fetch(`/api/v1/attributes/${id}`).then(response => response.json())
}
...
<FormDataConsumer>
{
async ({ formData, scopedFormData, getSource, ...rest }) => {
return await JSON.stringify(getAttrItem(scopedFormData.single_attributes_label));
}
}
</FormDataConsumer>
But when I use this one, it works in the console:
<FormDataConsumer>
{
({ formData, scopedFormData, getSource, ...rest }) => {
fetch('/api/v1/attributes/'+scopedFormData.single_attributes_label)
.then(res => res.json())
.then(data => {
console.log(JSON.stringify(data));
//return JSON.stringify(data);
resolve(JSON.stringify(data));
});
return JSON.stringify(scopedFormData);
}
}
</FormDataConsumer>
Should I use this FormDataConsumer for filling an object and then inside the other FormDataConsumer check the object?
回答1:
You might wanna do something like this:
const MyComponent = props => {
const [data, setData] = useState();
useEffect(() => {
fetch("/api/v1/attributes/" + props.attribute)
.then(res => res.json())
.then(data => {
setData(data);
});
}, [props.attribute]);
if (!data) {
return <someloadingindicator />;
}
// now you got your data. you can now return some component that uses the data here
};
// now in your component where using the FormDataConsumer
<FormDataConsumer>
{({ formData, scopedFormData, getSource, ...rest }) => {
return <MyComponent attribute={scopedFormData.single_attributes_label} />;
}}
</FormDataConsumer>;
回答2:
While you can run JavaScript expressions in JSX, it is not a good pattern to bloat it with too much JavaScript logic within JSX. The above logic should be handled within the componentDidMount()
lifecycle hook for class components, or in the useEffect
hook, for functional components.
In your FormDataConsumer
componentDidMount() {
fetch('/api/v1/attributes/'+scopedFormData.single_attributes_label)
.then(res => res.json())
.then(data => {
console.log(data);
// do the rest here
});
}
or
useEffect(() => {
fetch('/api/v1/attributes/'+scopedFormData.single_attributes_label)
.then(res => res.json())
.then(data => {
console.log(data);
// do the rest here
});
}, []);
回答3:
My issue was fixed with this code:
<FormDataConsumer>
{
({ formData, scopedFormData, getSource, ...rest }) => {
return scopedFormData && formData && "type" in formData && <ReferenceInput label="Attribute Label" source={getSource('single_attributes_label')} reference={`attributes`} filter={{ document_type: formData.type }}>
<AutocompleteInput optionText="title" optionValue="id" />
</ReferenceInput>
}
}
</FormDataConsumer>
<FormDataConsumer>
{
({ formData, scopedFormData, getSource, ...rest }) => {
return "type" in formData && "single_attributes_label" in scopedFormData && <AttribValue source={getSource('single_attributes_value')} reference={`attributes`} filter={{ document_type: formData.type, id: scopedFormData.single_attributes_label, method: "getOptions" }} attribute={scopedFormData.single_attributes_label} {...rest} />
}
}
</FormDataConsumer>
const AttribValue = props => {
const [data, setData] = useState();
console.log('props', props);
useEffect(() => {
fetch("/api/v1/attributes/" + props.attribute)
.then(res => res.json())
.then(data => {
setData({ data });
});
}, [props.attribute, props.label]);
if (!data) {
return 'Please Wait...';
}
let newProp = Object.assign({}, props, { label: "Attributes Value" });
return data.data.attribute_type == 'multiselect' ? <ReferenceArrayInput {...newProp}><AutocompleteArrayInput optionText="text" optionValue="id" /></ReferenceArrayInput> : <ReferenceInput {...newProp}><AutocompleteInput optionText="text" optionValue="id" /></ReferenceInput>;
};
来源:https://stackoverflow.com/questions/59528291/how-can-i-use-an-asynchronous-javascript-function-like-fetch-inside-a-formdataco