React中的重构和清理代码-处理条件和包装器组件

问题描述 投票:0回答:1

是否有一种更干净的方法来对反应成分进行处理?说我有这样的事情:

<Track>
  <ProductLink>
    <Image ... /> 
    <Typography ...>{...}</Typography>
    <Typography ...>{...}</Typography>
  </ProductLink>
</Track>

有条件的话,就像这样:

{condition ? <Track><ProductLink> : <> }
  <Image ... /> 
  <Typography ...>{...}</Typography>
  <Typography ...>{...}</Typography>
{condition ? </ProductLink></Track> : </> }

还有另一种处理条件的方法吗?如果满足条件,则具有“跟踪”和“ ProductLink”组件,否则,仅显示“片段”组件。

javascript reactjs coding-style refactoring code-cleanup
1个回答
0
投票
我建议将TrackProductLink吊装到可重复使用的组件中,这样您就可以将其简化为一种情况。

例如:

import React from "react"; import PropTypes from "prop-types"; import Track from "./path/to/Track"; import ProductLink from "./path/to/ProductLink"; const TrackProduct = ({ children, isTracked }) => ( isTracked ? <Track> <ProductLink> {children} </ProductLink> </Track> : children ); TrackProduct.proptTypes = { children: PropTypes.node.isRequired, isTracked: PropTypes.bool.isRequired }; export default TrackProduct;

然后导入上述可重用组件并通过state对其进行控制:

import React from "react"; import TrackProduct from "./path/to/TrackProduct"; import Image from "./path/to/Image"; import Typography from "./path/to/Typography"; import Button from "./path/to/Button"; class Example extends Component { state = { isTracked: false }; toggleTrack = () => this.setState(prevState => ({ track: !prevState.isTracked })) render = () => ( <TrackProduct isTracked={this.state.isTracked}> <Image ... /> <Typography ...>{...}</Typography> <Typography ...>{...}</Typography> <Button onClick={this.toggleTrack}> {!this.state.isTracked ? "Track" : "Untrack"} Product </Button> </TrackProduct> ) }; export default Example;


如果上述方法无法正常工作和/或过于重复,则可以使用渲染道具,该道具将其自身的状态和类字段传递给要控制的子功能(相对于包装HOC,我更喜欢这种方法,因为它们更易于测试)。

例如:

import React, { Component } from "react"; import PropTypes from "prop-types"; import Track from "./path/to/Track"; import ProductLink from "./path/to/ProductLink"; class TrackProduct extends Component { state = { isTracked: false }; toggleTrack = () => this.setState(prevState => ({ track: !prevState.isTracked })) render = () => { const renderedChildren = this.props.children({ isTracked: this.state.isTracked, toggleTrack: this.toggleTrack }); return ( isTracked ? <Track> <ProductLink> {renderedChildren} </ProductLink> </Track> : renderedChildren ) }; }; TrackProduct.proptTypes = { children: PropTypes.func.isRequired, }; export default TrackProduct;

然后导入上述可重用的渲染道具组件,并通过TrackProduct传递的道具(isTrackedtoggleTrack)对其进行控制:

import React from "react"; import TrackProduct from "./path/to/TrackProduct"; import Image from "./path/to/Image"; import Typography from "./path/to/Typography"; import Button from "./path/to/Button"; const Example = () => ( <TrackProduct> {({ isTracked, toggleTrack }) => ( <> <Image ... /> <Typography ...>{...}</Typography> <Typography ...>{...}</Typography> <Button onClick={toggleTrack}> {!isTracked ? "Track" : "Untrack"} Product </Button> </> )} </TrackProduct> ); export default Example;

有关渲染道具的更多信息,可以在此Phoenix ReactJS conference talk中找到。
© www.soinside.com 2019 - 2024. All rights reserved.