Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 乐观渲染&;使用效果_Reactjs_React Hooks_Use Effect - Fatal编程技术网

Reactjs 乐观渲染&;使用效果

Reactjs 乐观渲染&;使用效果,reactjs,react-hooks,use-effect,Reactjs,React Hooks,Use Effect,TL'DR:在对API调用使用useEffect时,有没有一种方法可以悲观地操作状态更改 假设您编写了一个显示分页/排序数据网格的组件,并为该组件编写了一个类似于此假示例的useEffect: useffect(()=>{ 取回(`https://some-random-api.com/data/page/{paging}/sort/{sorting}`) .then(response=>response.json()) .然后(数据=>setState({ 数据 })); },[分页、排序]

TL'DR:在对API调用使用useEffect时,有没有一种方法可以悲观地操作状态更改

假设您编写了一个显示分页/排序数据网格的组件,并为该组件编写了一个类似于此假示例的useEffect:

useffect(()=>{
取回(`https://some-random-api.com/data/page/{paging}/sort/{sorting}`)
.then(response=>response.json())
.然后(数据=>setState({
数据
}));

},[分页、排序]按照您描述它的方式,听起来您的组件的其余部分的结构如下

[state, setState] => useState(initialState)
[paging, setPaging] => useState(initialPaging)
[sorting, setSorting] => useState(initialSort)

useEffect(() => {
  fetch(`https://some-random-api.com/data/page/{paging}/sort/{sorting}`)
    .then(response => response.json())
    .then(data => setState({
      data
    }));
}, [paging, sorting]);

return <div>
    <span>Current page is {paging}</span>
    <Button onClick={() => setPaging(page => page + 1)}>Nav Next</Button>
    <Button onClick={() => setPaging(page => page - 1)}>Nav Prev</Button>
    // ... and so on and so forth
</div>
在实践中:

// Make factory instance
const factory = new pessimistFactory();

// Register state and effects
factory.registerState('paging', initialPaging)
factory.registerState('sorting', initialSorting)
factory.registerEffect('fetchData', () => fetch(`https://some-random-api.com/data/page/{paging}/sort/{sorting}`))

// Make the hooks
const {theState, hopefulState, effects} = factory.makeHooks();

// Implement hooks in component
const SomeComponent = () => {
  const [state, setState] = theState();
  const [pendingState, setPendingState] = hopefulState();

  effects.forEach(useEffect => useEffect());

  return <div>displayed stuff</div>
}
//生成工厂实例
常量工厂=新工厂();
//登记国和效力
factory.registerState('paging',initialPaging)
factory.registerState('sorting',initialSorting)
registerEffect('fetchData',()=>fetch(`https://some-random-api.com/data/page/{paging}/sort/{sorting}`)
//做钩子
const{theState,hoppentate,effects}=factory.makeHooks();
//在组件中实现钩子
常量SomeComponent=()=>{
const[state,setState]=状态();
常量[pendingState,setPendingState]=希望状态();
effects.forEach(useffect=>useffect());
返回显示的内容
}
最棘手的部分是设置
make悲观效果
效果,以读取和处理由生成的
setState
s创建的值和回调,我意识到如果在编写时完全破坏了这些值和回调

我现在没有时间真正弄清楚细节,但我认为这必须是可能的,因为有了新的挂钩,比如


不过,我确实喜欢这个想法,所以等我有时间的时候我会想办法解决这个问题。如果您在此之前创建了一个工作工厂类,或者如果有人有一个完全不同的更好的解决方案,我将非常有兴趣看到它。

聪明!我可能会这样做,然后将状态放在一个useState中,并使用回调setState API进行更新。或用户教育者。唯一的问题是,我不想重复这种复杂性(对于同一个应用程序中的其他API调用),也不想在依赖项列表增长的情况下维护这种复杂性。我确实想知道是否有办法提取/抽象/封装可重用的钩子。一个UsePessimiceffect钩子,如果你愿意。。。也许有办法。我需要和它玩一会儿。谢谢我同意你关于复杂性和封装性的反馈,我更新了我的答案作为回应。
class pessimistFactory {
  constructor(){
    this.state = {};
    this.effects = [];
  }
  // util from https://dzone.com/articles/how-to-capitalize-the-first-letter-of-a-string-in
  ucfirst = (string) => string.charAt(0).toUpperCase() + string.slice(1);

  registerState(param, initialVal){
    this.state[param] = initialVal;
  }

  makePessimisticEffect = (callback, dependencies) => useEffect(() => {
    async function handlePessimistically(){
      try {
        const result = await callback(...dependencies);
        // update theState with result
        setState({...hopefulState, result})
      }catch(err){
        // reset hopefulState and handle error
        setHopefulState({...theState})
      }
    }

    // Do something if some action pending
    if(/* pending and current state not the same */) handlePessimistically();

  }, [callback, dependencies]);

  registerEffect(callback, dependencies = []){
    this.effects.push(
      this.makePessimisticEffect(callback, dependencies)
    );
  }

  makeHooks = () => {
    const initialState = useState(this.state);
    return {
      theState: initialState,
      hopefulState: initialState,
      effects: this.effects
    }
  }
}
// Make factory instance
const factory = new pessimistFactory();

// Register state and effects
factory.registerState('paging', initialPaging)
factory.registerState('sorting', initialSorting)
factory.registerEffect('fetchData', () => fetch(`https://some-random-api.com/data/page/{paging}/sort/{sorting}`))

// Make the hooks
const {theState, hopefulState, effects} = factory.makeHooks();

// Implement hooks in component
const SomeComponent = () => {
  const [state, setState] = theState();
  const [pendingState, setPendingState] = hopefulState();

  effects.forEach(useEffect => useEffect());

  return <div>displayed stuff</div>
}