Реагируйте , пользовательский крючок замедляет визуализацию

#reactjs #react-native #react-hooks #react-navigation #react-forms

#реагирует на #реагировать-родной #реагируют-крючки #реагировать-навигация #реагирующие формы

Вопрос:

Здравствуйте, я сделал пользовательский крюк, который идет рука об руку с компонентом для универсальных форм, однако я замечаю, что он работает медленно при изменении состояния.

 #customHook export const useFormController = (meta) =gt; {  const { setVisible, setLoading } = useContext(FeedBackContext);  const itemsRef = useRef([]);  const {  control,  setValue,  handleSubmit,  formState: { errors },  } = useFormlt;Partiallt;anygt;gt;({  mode: "onBlur",  shouldUnregister: true,  resolver: yupResolver(meta.validation),  });   const onRef = function (input) {  this.itemsRef.current[this.index] = input;  };   const onSubmit = (data: any) =gt; {  if(meta.onSubmit){  meta.onSubmit(data);  }else{  setVisible(true);  setLoading(true);  meta.service.submit(data);  }  };   const isJsonEmpty = (val = {}) =gt; {  return Object.keys(val).length == 0;  };  const onSubmitIditing = function () {  let index =   this.index;  if (isJsonEmpty(errors) amp;amp; this.end) {  handleSubmit(onSubmit)();  } else if (!this.end) {  this.itemsRef.current[index]._root.focus();  }  };  const setFields = (json) =gt; {  const items = Object.keys(json);  const values = Object.values(json)  console.log('Cambiando fields en formControllser...', json)  for (let i = 0; i lt; items.length; i  ) {  //console.log('Cambiando valores...', items[i], values[i])   setValue(items[i], values[i], { shouldValidate: true })  }  }    const getItems = () =gt; {  console.log('Meta namess', meta.names, meta);   if (!meta amp;amp; !meta.names) return [];   return meta.names.map(function (item, index) {  const isEnd =  meta.options amp;amp; meta.options[item] amp;amp; meta.options[item].end  ? true  : false;   const isSecure =  meta.options amp;amp; meta.options[item] amp;amp; meta.options[item].secure  ? true  : false;   const label = meta.alias ? meta.alias[item] : item;  const visible = meta.invisibles ? (meta.invisibles[item] ? false : true) : true;  const def = meta.defaults ? meta.defaults[item] : "";   const disabled = (val) =gt; {  const b = meta.disableds ? (meta.disableds[item] ? true : false) : false;  return b;  }   return {  name: item,  label: label,  disabled: disabled,  onRef: onRef.bind({ itemsRef: itemsRef, index: index }),  onSubmitEditing: onSubmitIditing.bind({  itemsRef: itemsRef,  index: index,  end: isEnd,  errors: errors,  }),  visible: visible,  setFields,  defaultValue: def,  errors: errors,  secureTextEntry: isSecure,  styles: styles,  control: control,  options: meta.options[item] ? meta.options[item] : null,  };  });  }   const getData = useMemo(() =gt; {  console.log('Get data calback v2', meta);  return {  handleSubmit,  items: getItems(),  onSubmit,  errors,  setFields  };  }, [meta])    return getData; };     export const Client: React.FClt;anygt; = React.memo(({ navigation, route }) =gt; {    const {  alias,  defaults,  ubigeoSeleccionado,  setUbigeoSeleccionado,  editable,  inputLabel,  search,  getDisabled,  getInvisibles,  getAlias,  getDefaults,  disableds,  invisibles,  searchVisible,  idTypeDocument,  currentTypeDocument,  allTypeDocuments,  onValueChange,  onChangeText } = useContext(CreateClientContext);  const [mode, setMode] = useState(() =gt; {  return route?.params?.mode;  })  const [client, setClient] = useState(() =gt; {  return route?.params?.client;  })  const { dispatchClient } = useContext(GlobalContext);  const clientService = useClientService();  const ref = useRef(0);  const options = useMemo(() =gt; {   return {  names: ["ane_numdoc", "ane_razsoc", "ane_alias", "ane_email", "ane_tel", "ane_tel2", "ane_dir"],  validation: clientValidation,  alias: alias,  defaults: defaults,  disableds: disableds,  service: {  submit: (data) =gt; {  const parse = { ...data, ubigeo_id: ubigeoSeleccionado.ubi_id, ane_tipo_cp: 2, ane_tipdoc: currentTypeDocument.id }  if (mode == "update") {  //console.log('Actualizando...', client.id, parse);  clientService.updateById(client.id, parse)  .then(ok =gt; {  Alert.alert('Actualizaciòn de cliente', "Cliente Actualizado")  dispatchClient({  type: 'create',  payload: ok  });   setTimeout(() =gt; {  navigation.navigate('App', {  screen: "Clients"  })  }, 500)   }).catch(e =gt; {  Alert.alert('Actualizaciòn de cliente', "No se pudo actualizar")  })   } else {  clientService.create(parse)  .then(ok =gt; {  dispatchClient({  type: 'create',  payload: ok  });  Alert.alert('Cliente', "Cliente creado")   setTimeout(() =gt; {  navigation.navigate('App', {  screen: "Clients"  })  }, 500)  })  .catch(e =gt; {  (e);  Alert.alert('Error', "No se pudo crear el cliente")  })  }  }  },  invisibles: invisibles,  options: {  ane_dir: {  end: true  },  }  }   }, [getDisabled,  getInvisibles,  getAlias,  getDefaults])  const { items, handleSubmit, onSubmit, errors, setFields } = useFormController(options);   useEffect(() =gt; {  ref.current  ;  })   useEffect(() =gt; {  if (route.params) {  console.log('Ref current', ref.current);  setMode(route.params.mode);  setClient(route.params.client);  }  }, [route.params])  useEffect(() =gt; {  // console.log('Mode', mode, client.id);  if (mode == "update" amp;amp; client) {  console.log('cambiando fields'), ref;  setFields(client)  }  }, [mode, client])   // useEffect(()=gt;{   // },[instanceDocument])   useEffect(() =gt; {  console.log('Cambiando cliente...', mode, client);  console.log(ref.current);  }, [client])   useEffect(() =gt; {  //Creación  console.log('set defaults..', ref.current);  if (Object.keys(defaults).length gt; 0) {  setFields(defaults)  }  }, [getDefaults])  console.log('Current', ref.current);  return (  lt;StyleProvider style={getTheme(material)}gt;  lt;Container style={{ backgroundColor: "#FAF9FE" }}gt;  lt;Content style={GlobalStyles.mainContainer}gt;  lt;Text style={GlobalStyles.subTitle}gt;Clientelt;/Textgt;  lt;PickerSearch  search={search}  editable={editable}  style={styles}  searchVisible={searchVisible}  placeholder={inputLabel}  pickerItems={allTypeDocuments}  onValueChange={onValueChange}  selectedValue={idTypeDocument}  onChangeText={onChangeText}  gt;lt;/PickerSearchgt;   lt;FormListController  // top={lt;Top /gt;}  items={items}  style={GlobalStyles}  gt;lt;/FormListControllergt;   lt;Bottom  ubigeoSeleccionado={ubigeoSeleccionado}  setUbigeoSeleccionado={setUbigeoSeleccionado}  onSubmit={handleSubmit(onSubmit)}  /gt;     lt;/Contentgt;  lt;AppFooter2 navigation={navigation} /gt;  lt;/Containergt;  lt;/StyleProvidergt;  ); });  export const FormListController: React.FClt;anygt; = React.memo(({ children, items = [], style, top = null, bottom = null }) =gt; {   console.log('%c Form list controlllser...', "background-color:#ccc");  console.log('items', items)  return (  lt;gt;  lt;Form style={!!style.form ? style.form : style.formContainer}gt;  {top}  {items.map((item: any, index) =gt; {   return lt;FormItemController {...item} key={index} /gt;;   })}    {bottom}   lt;/Formgt;  lt;/gt;  ); });   export const FormItemController: React.FClt;anygt; = React.memo((props: any) =gt; {  console.log('Form item controller print', props)  if (props.visible) {  return (  lt;gt;  lt;Controller  control={props.control}  render={  ({ field: { onChange, onBlur, value } }) =gt; {   return (  lt;Item regular style={props.styles.item}gt;  lt;Label style={props.styles.label}gt;{props.label}lt;/Labelgt;  lt;Input  onBlur={onBlur}  disabled={props.disabled(value)}  onChangeText={(value) =gt; onChange(value)}  secureTextEntry={props.secureTextEntry}  onSubmitEditing={props.onSubmitEditing}  value={value}  ref={props.onRef}  /gt;  lt;/Itemgt;  )  }   }   defaultValue={props.defaultValue}  name={props.name}  /gt;  {props.errors amp;amp; props.errors[props.name] amp;amp; (  lt;TextError value={props.errors[props.name].message} /gt;  )}  {/* {props.options amp;amp; props.options.errorEmpty amp;amp; props.errors[""] amp;amp; (  lt;TextError value={props.errors[""].message} /gt;  )} */}  lt;/gt;  );  }  else {  return lt;gt;lt;/gt;  } });  

Я использую тот же компонент для создания и редактирования клиента, но при редактировании и просмотре FormItemController временной интервал журналов составляет менее 1 секунды, однако он отображается только через 8 или 10 секунд.

Это вывод моих журналов.

 Update cliente... 500ms   set defaults.. 77 Client num render 77 Client num render 78 Client num render 79 Client num render 80 Client num render 81 Client num render 82 Client num render 83 Client num render 84 Client num render 85 Client num render 86 Client num render 87 Client num render 88 Client num render 89 Client num render 90 Client num render 91 Client num render 92 Client num render 93 Client num render 94 Client num render 95 Client num render 96 Client num render 97 Client num render 98 Client num render 99 Client num render 100 (6-8 seg)  

проблема, с которой я сталкиваюсь, заключается в том, что когда я редактирую, когда я использую формы для создания, у меня нет проблем, я не нахожу узкого места для улучшения и предотвращения его замедления.

Ответ №1:

Попробовав несколько вариантов, я понял, что при передаче значения SET я отправлял несколько нулей и объектов, которые не шли с формой, фильтруя эти данные, сделал окончательный проход рендеринга от 8 секунд до менее 1 секунды

 const setFields = (json) =gt; {  const items = Object.keys(json);  const values = Object.values(json)  for (let i = 0; i lt; items.length; i  ) {  if (!!values[i] amp;amp; typeof values[i] != 'object') {  setValue(items[i], values[i])  }   }  }  

Комментарии:

1. Просто небольшое возможное улучшение кода: повторите все сначала Object.entries(json) , вместо того чтобы брать ключи и значения отдельно.

2. спасибо, я все еще оптимизирую этот код