优雅的 ES6 方式在 React 中更新状态
Posted
技术标签:
【中文标题】优雅的 ES6 方式在 React 中更新状态【英文标题】:Elegant ES6 way to update state in React 【发布时间】:2017-11-12 15:30:37 【问题描述】:在 React 中更新 state
的语法发生了很大变化。我正在尝试找到最简单、最优雅的方式来启动和更新它。
得到这个 RN 代码:
const quotes = require('./quotes.json')
class QuoteScreen extends Component
state =
QuoteIndex: 0
render()
return (
<Image ...>
<View ...>
...
<ButtonNextQuote
onPress=() =>
this.setState((prevState, props) =>
return
QuoteIndex: (prevState.QuoteIndex + 1) % (quotes.length - 1)
)
/>
</View>
</Image>
)
是否可以减少state
在onPress
中的更新?
希望避免调用匿名函数两次,但又不想引用和绑定处理程序。还想避免使用return
..
【问题讨论】:
【参考方案1】:我会将更新函数存储在类外的变量中,例如
const newState = (QuoteIndex: i) => (QuoteIndex: (i + 1) % nQuotes);
(当然你可以选择以任何你喜欢的方式定义函数,如果不内联,也许“简洁”对你来说不再那么重要了)
然后你就可以拨打this.setState(newState)
:
onPress=() => this.setState(newState)
【讨论】:
【参考方案2】:我会这样做。我在 setState 的回调 (prevState) 的第一个参数中使用了object destructuring,并且出于性能原因,我使用了单独的函数而不是匿名函数。另外请注意,我不需要手动将函数绑定到this
,因为我已经为它使用了箭头函数。
const quotes = require('./quotes.json')
class QuoteScreen extends Component
state =
QuoteIndex: 0
handleUpdateState = () =>
this.setState(( QuoteIndex ) => (
QuoteIndex: (QuoteIndex + 1) % (quotes.length - 1)
));
render()
return (
<Image ...>
<View ...>
...
<ButtonNextQuote
onPress=this.handleUpdateState
/>
</View>
</Image>
)
【讨论】:
由于这个问题是用 ES6 标记的,因此可能值得指出您正在使用实验性功能(公共类字段)并简要说明启用它们需要做什么。 对不起,我的错。基本上你有这个开箱即用的功能,最新版本的 babel 集成到 create-react-app 和 react-native 的依赖列表中。这是E6+,谢谢指出【参考方案3】:我认为一个流行的好方法是
通过向 this.setState
提供回调来使用“功能性 setState”,以避免批量状态更新中出现一些奇怪的情况
“将状态变化与组件类分开声明”,以便获得新状态的函数可以单独重用和测试。
查看this article,了解 Dan Abramov 的推文对这种方法的详细解释
例子:
const quotes = require('./quotes.json')
// keep pure function outside component to be reusable, testable
const getQuoteIndex = ( QuoteIndex ) => (
QuoteIndex: (QuoteIndex + 1) % (quotes.length - 1)
)
class QuoteScreen extends Component
state =
QuoteIndex: 0
// arrow function will take care of this binding
handlePress = () => this.setState(getQuoteIndex)
render()
return (
<Image ...>
<View ...>
...
<ButtonNextQuote
onPress=this.handlePress
/>
</View>
</Image>
)
【讨论】:
【参考方案4】:正如其他人所说,您希望避免每次运行 render
时都重新定义事件处理程序。我更喜欢将对象传递给setState
而不是回调函数:
_handlePress = () =>
this.setState(
QuoteIndex: (this.state.QuoteIndex + 1) % (quotes.length - 1)
);
;
onPress=this._handlePress
这更容易阅读,因为它明确了状态的来源。此外,您不必跟踪额外的回调函数。
【讨论】:
以上是关于优雅的 ES6 方式在 React 中更新状态的主要内容,如果未能解决你的问题,请参考以下文章