为什么我的 React Native 类组件返回错误:this.setState is not a function?

时间:2021-04-23 10:03:31

标签: javascript reactjs react-native

这是我的类组件的代码:

export class RenderButtons extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isCollapsed: false,
    };
  }

  render() {
    var buttonText = this.state.isCollapsed === true ? "Expand" : "Collapse";

    // helper components
    function _renderSquareButton({ item }) {
      return (
        <SquareButton
          name={item.name}
          onPress={() => this.props.pressHandler()}
        />
      );
    }

    function _header(name) {
      return (
        <View style={views.nameAndPriceContainer}>
          <Text style={text.headerTwo}>{name}</Text>
          <Button title={buttonText} onPress={() => toggleCollapsed()} />
        </View>
      );
    }

    function toggleCollapsed() {
      this.setState((currentState) => {
        return { isCollapsed: !currentState.isCollapsed };
      });
    }

    return (
      <FlatList
        listKey={this.props.name}
        ListHeaderComponent={_header(this.props.name)}
        data={this.props.data}
        extraData={this.props.data}
        renderItem={_renderSquareButton}
        numColumns={4}
        refreshing={true}
        extraData={this.props.data}
        keyExtractor={(item, index) => item.name + index}
        ListEmptyComponent={null}
      />
    );
  }
}

当我尝试按下展开/折叠按钮并说“未定义不是函数(正在评估'this.setState({ ... })”时出现问题,所以我假设它与 toggleCollapsed 函数有关。

编辑,谢谢大家问题已经解决。这是任何感兴趣的人的工作代码:

export class RenderButtons extends React.Component {
    constructor( props ){
        super( props );
        this.state = {
            isCollapsed:false,
        }
        this._renderSquareButton = this._renderSquareButton.bind(this); 
        this._header = this._header.bind(this);
        this.toggleCollapsed= this.toggleCollapsed.bind(this);
    }

    // helper components
    _renderSquareButton({ item }){
        return <SquareButton name={item.name} onPress={()=>this.props.pressHandler()} />
    }

    _header( name ){
       var buttonText = this.state.isCollapsed === true ? 'Expand' : 'Collapse';
        return(
            <View style={ views.nameAndPriceContainer }>
                <Text style={ text.headerTwo }>{ name }</Text>
                <Button title= { buttonText } onPress={()=> this.toggleCollapsed() } />
            </View>
        )
    }
    
    toggleCollapsed(){
        this.setState( currentState => {
            return { isCollapsed: !currentState.isCollapsed };
        });
    }


    render(){
        switch( this.state.isCollapsed ){
            case false:
                return (
                    <FlatList
                        listKey={ this.props.name }
                        ListHeaderComponent={this._header( this.props.name )}
                        data={ this.props.data } extraData={ this.props.data }
                        renderItem={ this._renderSquareButton }
                        numColumns={ 4 }
                        refreshing={ true }
                        extraData={ this.props.data }
                        keyExtractor={( item, index )=> item.name + index }
                        ListEmptyComponent={ null }
                    />
                )
            break;
            case true:
                return this._header( this.props.name )
        }
    }
}

4 个答案:

答案 0 :(得分:1)

将您的 ToggleCollapsed 更改为以下内容

function toggleCollapsed(){
  this.setState({
    isCollapsed: !this.state.isCollapsed;
   });
 }

答案 1 :(得分:1)

您需要更新一些内容:

  • toggleCollapsed移到render外面。
  • 更新onPress={this.toggleCollapsed}
  • this.toggleCollapsed = this.toggleCollapsed.bind(this) 中添加 constructor,在 this.state 之后

答案 2 :(得分:1)

只需像这样在 toggleCollapsed 中绑定函数 constructor

    constructor( props ){
        super( props );
        this.state = {
            isCollapsed:false,
        }
     this.toggleCollapsed = this.toggleCollapsed.bind(this);
    }

这应该可以解决您的问题。

无论如何,我建议您以这种方式重构您的代码:

export class RenderButtons extends React.Component {
    constructor( props ){
        super( props );
        this.state = {
            isCollapsed:false,
        }
        this._renderSquareButton = this._renderSquareButton.bind(this); 
        this._header = this._header.bind(this);
        this.toggleCollapsed= this.toggleCollapsed.bind(this);
    }

    // helper components
    _renderSquareButton({ item }){
        return <SquareButton name={item.name} onPress={()=>this.props.pressHandler()} />
    }

    _header( name ){
       var buttonText = this.state.isCollapsed === true ? 'Expand' : 'Collapse';
        return(
            <View style={ views.nameAndPriceContainer }>
                <Text style={ text.headerTwo }>{ name }</Text>
                <Button title= { buttonText } onPress={()=> this.toggleCollapsed() } />
            </View>
        )
    }
    
    toggleCollapsed(){
        this.setState( currentState => {
            return { isCollapsed: !currentState.isCollapsed };
        });
    }


    render(){
    return (
        <FlatList
            listKey={ this.props.name }
            ListHeaderComponent={this._header( this.props.name )}
            data={ this.props.data } extraData={ this.props.data }
            renderItem={ this._renderSquareButton }
            numColumns={ 4 }
            refreshing={ true }
            extraData={ this.props.data }
            keyExtractor={( item, index )=> item.name + index }
            ListEmptyComponent={ null }
        />
    )
    }
}

答案 3 :(得分:0)

import React from "react";
const [collapsed, setCollapsed] = React.useState(false);

也许这对你有帮助

也无需将 bool 与 === true 进行比较。

let buttonText = this.state.isCollapsed ? 'Expand' : 'Collapse';