【问题标题】:receiving null is not an object (evaluating ' this.state.search')接收 null 不是对象(评估“this.state.search”)
【发布时间】:2017-05-08 12:07:34
【问题描述】:

我收到 null 不是对象(评估“this.state.search”)我是 react-native 的新手,所以不能 100% 确定发生了什么。感谢您的帮助。

这是我的基本搜索栏:

use strict';

import React, { Component }                             from 'react';
import { StyleSheet, Text, View, TextInput, Button }    from 'react-native';
import renderIf                                         from '../common/renderIf';
import { Container, Header, Title, Content, Icon, CardItem, Card, Input, InputGroup} from 'native-base';




export default class SearchBar extends Component {



  render() {
    return (
                <Card> 
                    <CardItem searchBar rounded>                      
                        <InputGroup>
                            <Icon name="ios-search" />
                            <Input placeholder="Search" value={this.state.search} onChangeText={(text) => this.setState({search:text})} onSubmitEditing={()=>this.search()}/>
                        </InputGroup>
                    
                    </CardItem>
                </Card>
    );
  }
}

这是从搜索栏中获取输入的文本并显示结果:

'use strict';

import React, { Component }                             from 'react';
import { StyleSheet, Text, View, TextInput, Button }    from 'react-native';
import renderIf                                         from '../common/renderIf';
import { Container, Content, Icon, CardItem, Card, Thumbnail, Title, List, ListItem} from 'native-base';
import { Col, Row, Grid }                               from "react-native-easy-grid";

export default class AddMovieResults extends Component {

    search() {   
    // Set loading to true when the search starts to display a Spinner        
    this.setState({            
        loading: true          
    });

    var that = this;        
    return fetch('http://www.omdbapi.com/?s=' +this.state.search)       
    .then((response) => response.json())            
    .then((responseJson) => {      
        // Store the results in the state variable results and set loading to                 
         // false to remove the spinner and display the list of repositories                
          that.setState({                    
        results: responseJson,                    
        loading: false                
    });
    return responseJson.Search;            
}) 
    .catch((error) => {
        that.setState({                    
        loading: false                 
    });
        console.error(error);        
    });    
}


  render() {
    return (

                    <Card scrollEnabled={true}> 
                        <CardItem button >  

                           <List dataArray={this.state.results.items} renderRow={(item) =>               
                                <ListItem button >
                                <Row> 

                                  <Col size={1}>
                                    <Thumbnail square style={{ height: 90, width:60, bottom:6,justifyContent: 'center',}} source={{uri: item.poster}} /> 
                                  </Col>  

                                  <Col size={3}>
                                    
                                    <Row size={3}> 
                                    <Text style={{ fontSize: 25, color: '#DD5044',justifyContent: 'center',}}>{item.title}</Text>      
                                    </Row>

                                    <Row size={1}>
                                    <Text style={{ fontSize: 15, color: '#DD5044',}}>{item._year_data}</Text>    
                                   </Row>
                                   
                                   </Col>
                                  </Row>  
                                </ListItem>                            
                            } />
                        </CardItem>
                    </Card> 
    );
  }
}

这是我的索引文件,它在一页上显示上述文件:

'use strict';

import React, { Component }                             from 'react';
import { StyleSheet, Text, View, TextInput, Button }    from 'react-native';
import renderIf                                         from '../common/renderIf';
import { Container, Header, Title, Content}             from 'native-base';
import { Col, Row, Grid }                               from "react-native-easy-grid";

import AddMovieResults                                  from './AddMovieResults';
import SearchBar                                        from './SearchBar';


export default class AddNewMovie extends Component {




  render() {
    return (
        <Container scrollEnabled={false}>
            <Header>
                <Title> Add Movie</Title>
            </Header>
            <Content>
        <Grid>
            <Col>
            {/* import search bar */}
                <SearchBar/>
            {/*import search results*/}
                <AddMovieResults/>
            </Col>
        </Grid>
            </Content>
        </Container>
    );
  }
}

【问题讨论】:

  • 您正试图在&lt;SearchBar/&gt; 中调用this.search() 一个没有搜索方法的组件...该方法调用总是会抛出错误

标签: javascript null react-native


【解决方案1】:

状态不是全局的,它对每个组件都是本地的,因此您需要将其作为道具传递给对象。

然而,这里的问题是,当您定义搜索栏并添加电影结果时,您需要找到一种方法从 SearchBar 传回状态。

为此,您可以传递一个引用函数来更新 AddNewMovie 的状态:

将以下函数添加到您的 addNewMovie 类:

updateAddNewMovieState = (newData) => {
	this.setState({search:newData})
}

接下来将其传递给搜索栏类:

<SearchBar
  updateState = {this.updateAddNewMovieState}
  currentState = {this.state.search}
/>

现在使用 this.props.currentState 访问搜索状态,使用 this.props.updateState(newState) 从搜索栏类修改 AddNewMovie 中的状态。

最后,将变量传递给 AddMovieResults:

<AddMovieResults
  search={this.state.search}
/>

然后您可以通过 this.props.search 访问 AddMovieResults 中的变量。

虽然这种方法相对简单,但如果您传递许多变量,它很快就会变得复杂,为此我推荐https://github.com/reactjs/react-redux,它允许您通过动作函数和归约状态更清晰地存储变量。

我还建议在每个组件构造函数中定义您的状态变量,以便更清楚地了解它们的定义位置:

constructor(props) {
    super(props);

    this.state = {
      something: "Something"
    };
  }

【讨论】:

    【解决方案2】:

    您需要在构造函数中绑定您的函数,以便能够在继承的 React 类函数(如 renderconstructor 等)之外访问 this

    export default class AddMovieResults extends Component {
        constructor(props){
             super(props);
             this.search = this.search.bind(this);
        }
        search() {   
        // Set loading to true when the search starts to display a Spinner        
            this.setState({            
                loading: true          
            });
        }
        ...
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2017-09-26
      • 2022-01-05
      • 2021-10-20
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多