簡體   English   中英

如何將此 React 鈎子組件轉換為功能組件

[英]How to convert this React hook component into a functional component

下面是我想轉換為鈎子的代碼 -

  const App = () => {

  const [visible, setVisible] = React.useState(false);

  const openMenu = () => setVisible(true);
  const closeMenu = () => setVisible(false);
  const [barClicked, setbarClicked] = React.useState(false);
  const [lineClicked, setlineClicked] = React.useState(false);
  const [pieClicked, setpieClicked] = React.useState(false);

  const BarCharts = () => {
    const fill = 'rgb(134, 65, 244)'
    const data = [50, 10, 40, 95, -4, -24, null, 85, undefined, 0, 35, 53, -53, 24, 50, -20, -80]
    return (
      <View style={styles.sectionContainer}>
        <BarChart style={{ height: 200 }} data={data} svg={{ fill }} contentInset={{ top: 30, bottom: 30 }}>
          <Grid />
        </BarChart>
      </View>
    );
  };

  const LineCharts: () => React$Node = () => {
    const data = [50, 10, 40, 95, -4, -24, 85, 91, 35, 53, -53, 24, 50, -20, -80]
    return (
          <View style={styles.sectionContainer}>
            <LineChart
                style={{ height: 200 }}
                data={data}
                svg={{ stroke: 'rgb(134, 65, 244)' }}
                contentInset={{ top: 20, bottom: 20 }}
            >
                <Grid />
            </LineChart>
          </View>
    );
  };

  const PieCharts: () => React$Node = () => {
    const data = [50, 10, 40, 95, -4, -24, 85, 91, 35, 53, -53, 24, 50, -20, -80]
    const randomColor = () => ('#' + ((Math.random() * 0xffffff) << 0).toString(16) + '000000').slice(0, 7)
    const pieData = data
            .filter((value) => value > 0)
            .map((value, index) => ({
                value,
                svg: {
                    fill: randomColor(),
                    onPress: () => console.log('press', index),
                },
                key: `pie-${index}`,
            }))
    return (
          <PieChart style={{ height: 200 }} data={pieData} />
    );
  };

  return (
    <Provider>
      <View
        style={{
          paddingTop: 50,
          flexDirection: 'row',
          justifyContent: 'center',
        }}>
          <Menu
            visible={visible}
            onDismiss={closeMenu}
            anchor={<Button onPress={openMenu}>Show menu</Button>}>
            <Menu.Item onPress={() => setbarClicked(!barClicked)} title="Item 1" />
            <Menu.Item onPress={() => setlineClicked(!lineClicked)} title="Item 2" />
            <Menu.Item onPress={() => setpieClicked(!pieClicked)} title="Item 3" />
          </Menu>
        </View>
        <View>
          <Button onPress={() => setbarClicked(!barClicked)}></Button>
          {barClicked && <BarCharts />}
          <Button onPress={() => setlineClicked(!lineClicked)}></Button>
          {lineClicked && <LineCharts />}
          <Button onPress={() => setpieClicked(!pieClicked)}></Button>
          {pieClicked && <PieCharts />}
       </View>
       <View style={styles.container}>
       </View>
    </Provider>
  );
};

export default App; 

這是在單擊 SHOW MENU > Item 1 后應該執行的操作。 在此處輸入圖片說明 我嘗試自己做,但它返回錯誤。 - '找不到變量 barClicked'。 下面是我想出的

  export default class MyComponent extends React.Component {

  state = {
    visible: false,
    barClicked: false,
    lineClicked: false,
    pieClicked: false
  };

  _openMenu = () => this.setState({ visible: true });

  _closeMenu = () => this.setState({ visible: false });

  _setbarClicked = () => this.setState({ barClicked: true });

  _setlineClicked = () => this.setState({ barClicked: true });

  _setpieClicked = () => this.setState({ barClicked: true });


  render() {
    return (
      <Provider>
        <View
          style={{
            paddingTop: 50,
            flexDirection: 'row',
            justifyContent: 'center'
          }}>
          <Menu
            visible={this.state.visible}
            onDismiss={this._closeMenu}
            anchor={
            <Button onPress={this._openMenu}>Show menu</Button>}>
            <Menu.Item onPress={() => this._setbarClicked(!barClicked)} title="Item 1" />
            <Menu.Item onPress={() => this._setlineClicked(!lineClicked)} title="Item 2" />
            <Menu.Item onPress={() => this._setpieClicked(!pieClicked)} title="Item 3" />
          </Menu>
        </View>
        <View>
          <Button onPress={() => this._setbarClicked(!barClicked)}></Button>
          {this.barClicked && <BarCharts />}
          <Button onPress={() => this._setlineClicked(!lineClicked)}></Button>
          {this.lineClicked && <LineCharts />}
          <Button onPress={() => this._setpieClicked(!pieClicked)}></Button>
          {this.pieClicked && <PieCharts />}
       </View>
      </Provider>
    );
  }
} 

我使用了react-native-svg-chart庫中的BarChartLineChartPieChart

問題

您沒有正確引用任何狀態變量,並且您的處理程序不使用任何參數。 您的所有處理程序也錯誤地引用了您的barClicked狀態。

_setbarClicked = () => this.setState({ barClicked: true });

_setlineClicked = () => this.setState({ barClicked: true });

_setpieClicked = () => this.setState({ barClicked: true });

解決方案

如果您希望處理程序采用參數,請按如下方式調整實現:

_setbarClicked = (barClicked) => this.setState({ barClicked });

_setlineClicked = (lineClicked) => this.setState({ lineClicked });

_setpieClicked = (pieClicked) => this.setState({ pieClicked });

並調整您的回調以正確引用狀態,即this.state. barClicked this.state. barClicked

render() {
  const { barClicked, lineClicked, pieClicked } = this.state;

  return (
    ...

    <Menu.Item onPress={() => this._setbarClicked(!barClicked)} title="Item 1" />
    <Menu.Item onPress={() => this._setlineClicked(!lineClicked)} title="Item 2" />
    <Menu.Item onPress={() => this._setpieClicked(!pieClicked)} title="Item 3" />

    ...

    <Button onPress={() => this._setbarClicked(!barClicked)}></Button>
    {barClicked && <BarCharts />}
    <Button onPress={() => this._setlineClicked(!lineClicked)}></Button>
    {lineClicked && <LineCharts />}
    <Button onPress={() => this._setpieClicked(!pieClicked)}></Button>
    {pieClicked && <PieCharts />}

    ...
  );
}

建議

由於您實際上只是在切換這些狀態值,因此只需在處理程序中執行此操作。

_setbarClicked = () => this.setState(prevState => ({ !prevState.barClicked }));

_setlineClicked = () => this.setState(prevState => ({ !prevState.lineClicked }));

_setpieClicked = () => this.setState(prevState => ({ !prevState.pieClicked }));

然后只需附加為非匿名回調。

render() {
  const { barClicked, lineClicked, pieClicked } = this.state;

  return (
    ...

    <Menu.Item onPress={this._setbarClicked} title="Item 1" />
    <Menu.Item onPress={this._setlineClicked} title="Item 2" />
    <Menu.Item onPress={this._setpieClicked} title="Item 3" />

    ...

    <Button onPress={this._setbarClicked}></Button>
    {barClicked && <BarCharts />}
    <Button onPress={this._setlineClicked}></Button>
    {lineClicked && <LineCharts />}
    <Button onPress={this._setpieClicked}></Button>
    {pieClicked && <PieCharts />}

    ...
  );
}

您需要將狀態對象放置在類組件的構造函數中(最好)。

export default class MyComponent extends React.Component {

  constructor(props) {
     super(props)
     this.state = {
        visible: false,
        barClicked: false,
        lineClicked: false,
        pieClicked: false
     };
  }

  ...

並將您的調用從this._setbarClicked(!barClicked)更改為this._setbarClicked(!this.state.barClicked)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM