【问题标题】:How can I use state inside recompose's `withPropsOnChange` HOC?如何在 recompose 的 `withPropsOnChange` HOC 中使用状态?
【发布时间】:2018-02-02 23:26:35
【问题描述】:

我想使用withPropsOnChange根据传入的props创建一个新的debounced函数。如果props改变了,它应该创建一个新函数。 withPropsOnChange 似乎非常适合这个,除了我需要在 createProps 回调中访问 this.state,而 recompose 不提供。

有哪些选择?即我如何创建一个属性(React 或 vanilla),它取决于/依赖于其他一些属性,并在这些属性更新时自动更新?


这是我现在所掌握的要点:

class MyClass extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            isOpen: false,
            isLoading: 0,
            isWaiting: false,
            searchQuery: '',
            options: [],
            value: undefined, 
            highlightedValue: undefined,
            scrollPos: 0,
        };
        if(props.options) {
            this.loadOptions = Lo.debounce(searchQuery => {
                this.setState(state => ({
                    isLoading: state.isLoading + 1,
                }));
                props.options(searchQuery).then(result => {
                    this.setState(state => ({
                        isLoading: state.isLoading - 1,
                        options: result.options,
                    }));
                });
            }, props.delay);
        }
    }
}

如您所见,我定义了一个名为this.loadOptions 的属性,它只是props.options 的去抖动副本,并带有一些状态处理。

目前这可以正常工作,但如果上游修改了props.optionsprops.delay,那么this.loadOptions 不会更新,因为我只在构造函数中执行此操作。

现在我可以componentWillUpdate 中再次执行所有这些操作,但实际上我只想在更新props.optionsprops.delay 时执行此操作,因为这是它仅有的两个依赖项。

我只是在寻找一种更简洁的设计模式来处理这类事情。现在我考虑它基本上只是“计算属性”(但我不能根据需要“重新计算”它——除非修改了这些属性,否则我每次都需要返回相同的实例)。

【问题讨论】:

  • 100k 声望和这么低质量的标题?
  • @slick ¯\_(ツ)_/¯ 它包含所有重要的关键字。我已经更新了标题。
  • 不要担心,不要冒犯马克,一切都好! :)
  • 你能不能写一些伪代码来进一步解释程序的流程/逻辑应该是怎样的?或者关于用例的更多细节。我看不出问题出在哪里。但这很可能只是我的大脑迟钝。
  • @jonahe 我用更具体的例子更新了这个问题。

标签: reactjs recompose


【解决方案1】:

因此,据我了解,您有一些当前位于组件内部的状态。并且您想在 createProps 回调中使用该状态。

是否可以使用 recompose 来提取内部状态(及其逻辑),withState

然后,如果您使用withState“开始”组合重构函数,则状态应该“进一步向下”作为道具可用。 (或者至少这是我的理解。)

const enhance = compose(
  // handle previously internal state
  withState('importantState', 'changeImportantState', 0),
  withHandlers({
    logicForChangingTheImportantState:
        props => () => props.changeImportantState(old =>  ({...old, moreImportant: 'xyz'}))
  }),
    // do your logic here
  withPropsOnChange(
    [], // ?? shouldMapOrKeys
    (props) => {
        return {
        thisPreviouslyDependedOnInternalState: props.importantState
      }
    }    
  ) 
);

【讨论】:

  • 我也许可以通过withState 将所有状态移动到道具中,但是我也必须将我所有的处理程序都移过来(就像你展示的那样),这比重构更多我想做。
  • 好的,可以理解。当您第一次编写代码时,像这样“外部化”状态要容易得多。我曾经尝试养成只编写简单/愚蠢的功能组件并使用withState(和redux)处理所有状态的习惯。但即便如此,当我不需要重构任何东西时,编写这样的代码还是有点困难和不直观。所以我的实验并没有持续多久。 /无意义的故事时间结束。
  • 我基本上做了同样的事情。尝试将我的所有状态都放在我的组件中。然后我发现了 recompose,试着让所有东西都“哑”了一段时间,然后我觉得这个组件太复杂了,不能让我哑,所以我开始用老式的方式写它,然后发现用 recompose 会更容易做一两件事,所以我把几个 HOC 带回来了……现在我搞砸了。
猜你喜欢
  • 2019-02-27
  • 2018-08-24
  • 2018-03-16
  • 2019-09-06
  • 1970-01-01
  • 2017-08-01
  • 2017-05-29
  • 2018-09-27
  • 2019-09-30
相关资源
最近更新 更多