【问题标题】:Convert React Native functional components to class components将 React Native 功能组件转换为类组件
【发布时间】:2020-02-03 04:40:13
【问题描述】:

我是 React Native 的新手,在学习了一些教程之后,我一起破解了这个,但现在我想在应用程序启动时加载一些 gif - 而不是在单击按钮之后。

做了一些研究,看起来功能组件不可能,我需要切换到类组件以使用生命周期功能,例如:

componentWillMount(){
        this.setState({data : inputObject});
    }

到目前为止,我读过的所有示例的组件中都没有函数,我不知道如何处理它们。因此,如果可以在应用程序开始使用它时调用一个函数,请告诉我如何,如果没有,我如何将此代码转换为类组件样式?谢谢!

import React, {useState} from 'react';
import {
  Dimensions,
  StyleSheet,
  SafeAreaView,
  View,
  Image,
  FlatList,
} from 'react-native';
import SearchInput from './SearchInput';

export default function App() {
  const [allGifResults, setAllGifResults] = useState([]);

  function addSearchResultsHandler(searchTerm) {
    console.log(searchTerm);
    setAllGifResults([]);
    fetchResults(searchTerm);
  }

  function allGifResultsHandler(url) {
    setAllGifResults(currentGifs => [...currentGifs, {id: url, value: url}]);
  }

  function fetchResults(searchTerm) {
    fetch(
      'http://api.giphy.com/v1/gifs/search?q=' +
        searchTerm +
        '&api_key=MKSpDwx7kTCbRp23VtVsP4d0EvfwIgSg&limit=50',
    )
      .then(response => response.json())
      .then(responseJson => {
        for (let item of responseJson.data) {
          allGifResultsHandler(item.images.fixed_height.url);
          console.log(item.images.fixed_height.url);
        }
      })
      .catch(error => {
        console.error(error);
      });
  }

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.screen}>
        <SearchInput onSearchButtonPressed={addSearchResultsHandler} />
      </View>

      <FlatList
        keyExtractor={(item, index) => item.id}
        data={allGifResults}
        numColumns={2}
        renderItem={itemData => (
          <Image
            source={itemData.item.value ? {uri: itemData.item.value} : null}
            style={styles.images}
          />
        )}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5FCFF',
  },
  screen: {
    margin: 10,
  },
  images: {
    width: Dimensions.get('window').width / 2 - 20,
    height: Dimensions.get('window').width / 2 - 20,
    margin: 10,
  },
});
import React, {useState} from 'react';
import {
  View,
  TextInput,
  TouchableOpacity,
  Text,
  StyleSheet,
} from 'react-native';

function SearchInput(props) {
  const [searchTerm, setSearchTerm] = useState('');

  function inputHandler(enteredText) {
    setSearchTerm(enteredText);
  }

  return (
    <View style={styles.inputContainer}>
      <TextInput
        placeholder="Search Term"
        style={styles.input}
        onChangeText={inputHandler}
        value={searchTerm}
      />
      <TouchableOpacity
        style={styles.searchButton}
        onPress={props.onSearchButtonPressed.bind(this, searchTerm)}>
        <Text style={styles.searchButtonText}>Search</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  inputContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'flex-start',
    marginBottom: 20,
  },
  input: {
    width: '70%',
    borderColor: 'black',
    borderWidth: 1,
    fontSize: 16,
  },
  searchButton: {
    height: 50,
    width: 100,
    backgroundColor: 'lightblue',
    marginLeft: 10,
  },
  searchButtonText: {
    height: 50,
    fontSize: 18,
    textAlign: 'center',
    textAlignVertical: 'center',
  },
});

export default SearchInput;

【问题讨论】:

  • 嗨,用这个代替

标签: react-native


【解决方案1】:
    import React, {useState} from 'react';
    import {
      Dimensions,
      StyleSheet,
      SafeAreaView,
      View,
      Image,
      FlatList,
    } from 'react-native';
    import SearchInput from './SearchInput';
    const [allGifResults, setAllGifResults] = useState([]);

    class App extends React.Component {
      constructor(props) {
          super(props);
          this.state = {

          };
        this.addSearchResultsHandler = this.addSearchResultsHandler.bind(this);
        this.allGifResultsHandler = this.allGifResultsHandler.bind(this);
        this.fetchResults = this.fetchResults.bind(this);
      }

      addSearchResultsHandler(searchTerm) {
        console.log(searchTerm);
        setAllGifResults([]);
        fetchResults(searchTerm);
      }

      allGifResultsHandler(url) {
        setAllGifResults(currentGifs => [...currentGifs, {id: url, value: url}]);
      }

      fetchResults(searchTerm) {
        fetch(
          'http://api.giphy.com/v1/gifs/search?q=' +
            searchTerm +
            '&api_key=MKSpDwx7kTCbRp23VtVsP4d0EvfwIgSg&limit=50',
        )
          .then(response => response.json())
          .then(responseJson => {
            for (let item of responseJson.data) {
              allGifResultsHandler(item.images.fixed_height.url);
              console.log(item.images.fixed_height.url);
            }
          })
          .catch(error => {
            console.error(error);
          });
      }
      render(){
         return (
            <SafeAreaView style={styles.container}>
              <View style={styles.screen}>
                <SearchInput onSearchButtonPressed={(data)=> this.addSearchResultsHandler(data)} />
              </View>

              <FlatList
                keyExtractor={(item, index) => item.id}
                data={allGifResults}
                numColumns={2}
                renderItem={itemData => (
                  <Image
                    source={itemData.item.value ? {uri: itemData.item.value} : null}
                    style={styles.images}
                  />
                )}
              />
            </SafeAreaView>
          );
      }
    }

    export default App;

    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
      },
      screen: {
        margin: 10,
      },
      images: {
        width: Dimensions.get('window').width / 2 - 20,
        height: Dimensions.get('window').width / 2 - 20,
        margin: 10,
      },
    });

   import React, {useState} from 'react';
import {
  View,
  TextInput,
  TouchableOpacity,
  Text,
  StyleSheet,
} from 'react-native';

const [searchTerm, setSearchTerm] = useState('');
class SearchInput extends React.Component {
  constructor(props) {
      super(props);
      this.state = {

      };
    this.inputHandler = this.inputHandler.bind(this);
  }

  inputHandler(enteredText) {
    setSearchTerm(enteredText);
  }

  render(){
    return (
      <View style={styles.inputContainer}>
        <TextInput
          placeholder="Search Term"
          style={styles.input}
          onChangeText={inputHandler}
          value={searchTerm}
        />
        <TouchableOpacity
          style={styles.searchButton}
          onPress={props.onSearchButtonPressed.bind(this, searchTerm)}>
          <Text style={styles.searchButtonText}>Search</Text>
        </TouchableOpacity>
      </View>
    );
  }
}
export default SearchInput;


const styles = StyleSheet.create({
  inputContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'flex-start',
    marginBottom: 20,
  },
  input: {
    width: '70%',
    borderColor: 'black',
    borderWidth: 1,
    fontSize: 16,
  },
  searchButton: {
    height: 50,
    width: 100,
    backgroundColor: 'lightblue',
    marginLeft: 10,
  },
  searchButtonText: {
    height: 50,
    fontSize: 18,
    textAlign: 'center',
    textAlignVertical: 'center',
  },
});

export default SearchInput;

【讨论】:

  • 我尝试使用此代码,但出现错误:Invariant Violation: Invalid hook call。钩子只能在函数组件的主体内部调用。有什么想法吗?
  • 试试这个链接https://github.com/facebook/react/issues/15628,https://reactjs.org/warnings/invalid-hook-call-warning.html
  • @Elango 嗨,希望你一切顺利。如果你能帮助我,我有一个关于 React Native 的问题。所以基本上我有一个类组件,现在我想转换为函数组件。但我无法在我的代码中转换这一行this.type = 'text'; 你能帮我吗stackoverflow.com/a/58559185/14582741
  • 你想动态设置输入类型?
猜你喜欢
  • 1970-01-01
  • 2020-06-22
  • 2021-05-29
  • 1970-01-01
  • 2021-06-13
  • 2020-06-23
  • 2020-10-27
  • 2021-10-21
相关资源
最近更新 更多