Closed WangLarry closed 3 years ago
can init state of component in stateChange function.
stateChange: (props) => {
if (!props.prevState) {
return new Promise((resolve) => {
// init state ....
});
});
}
// no more changes needed
return undefined;
},
above code can also fix AsyncMultiSelect display 'no options' #47
AsyncMultiSelect: {
renderer: AsyncMultiSelect,
stateChange: (props) => {
// if search filter has changed - return object with cleared items and
// change isLoading indication to true
if (!props.prevState || (props.prevState && (props.prevState.searchQuery !== props.state.searchQuery))) {
return { ...props.state, items: [], isLoading: true };
}
// else, if isLoading changes to true,
// begin search and return promise which resolves an object of: { items: [ ... ], isLoading: false }
if (props.state.isLoading) {
return new Promise((resolve) => {
// mock server call
mockService.search(props.state.searchQuery || '').then((items) => {
const viewItems = items.map(x => { return { label: x.name, value: x.id }; });
resolve({ ...props.state, items: viewItems, isLoading: false }); // items should contain objects that has { label, value }
});
});
}
// else - no more changes needed
return undefined;
},
},
@WangLarry True :) There are more ways, lets share them:
Upside - you init all your form configuration just one time in a single point - which is easy to track and change. Downside - the user might experience a latency in viewing the UI, so if the server taking time to respond this will not be the best UX experience.
Upside - better UX experience (the user immediately see the ui of the form when the page is loaded). Downside - 2 inits, and the user might be quick enough to do some action on the form which might be overwritten. Also might affect tests as well.
Upside - better UX experience (the user immediately see the ui of the form when the page is loaded). Also all the component "logic" and configuration remains in the component scope. Downside - if you want a single point in the system which will have all the initial form configuration - this will not serve it. Also - if you have multiple fields components which require initial data from the server - this might cause multiple calls to the server, instead of just one (But actually if your'e being smart you can have a server which fetch you all the components data in one call and cache it. And all the component use it to get the data, and only the first component which called it will cause the actual call to the server to occur. the rest will wait for the response.)
Note: Hooks of Side effects like "beforeInitForm" (before and after actions) are not meant to trigger any change in the form structure. For that we have the "actions" objects. Side effects are for stuff like - logging to the DB, google analytics or other stuff. This is why we don't pass the "actions" object to these hooks.
Choose the best practice for your app :)
Also all the component "logic" and configuration remains in the component scope.
It's important because we can config form, not write 'custom' codes for every form.
@WangLarry True and you can use the same form configuration for multiple forms :) For example if you have the field of "lastUpdated" for multiple forms you can define it only once - in a shared location.
I think that performance is considered lately.
Is your feature request related to a problem? Please describe. For some components, for example multiselect, it is normal that select's options come from backend server. How to init state(options or items) of these components when init form? I notice that react-editor custom codes do it when init model data.
Describe the solution you'd like Can configure component in model, set initComponentState function, then async call it in beforeInitForm.