【发布时间】:2020-02-05 20:42:50
【问题描述】:
作为一名 React Native 新手,我正在开发一个适用于 android 的应用程序。基本上,该应用程序使用户能够根据特定的搜索参数过滤数据库。
现在我尝试将类组件转换为功能组件。该组件只是加载一个预填充的(Realm-)数据库,显示一个等待用户输入的搜索栏,根据用户的输入执行数据库查询并显示结果。
在“旧”版本中,数据库设置是在componentDidMount() 期间完成的,现在我认为使用useEffect() Hook 可以完成这项工作,因为它可以替代componentDidMount()。但我发现,在没有任何 Hook 的情况下“裸”执行所有逻辑(我实际上想放入 Hook)就可以了。
我对这种行为感到很困惑,因为我没想到它会以这种方式工作。我肯定错过了什么。不幸的是,谷歌搜索没有给出答案。你能帮助我吗?下面是我所说的组件的代码,SearchBar.js非常感谢您的帮助!
import React, {useState} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {connect} from 'react-redux';
import {Header, Icon, Item, Input} from 'native-base';
import Realm from 'realm';
import fs from 'react-native-fs';
import {setInputValueSearchBar} from '../../../actions';
const SearchBar = props => {
let [inputValue, setInputValue] = useState(null);
const sendInputValueToReduxStore = text => {
setInputValue(text);
props.setInputValueSearchBar(text);
};
// from here on, I wanted to use useEffect() ...
const dogsSchema = {
name: 'realm',
properties: {
name: 'string?',
color: 'string?',
},
};
let realm = new Realm({
path: fs.DocumentDirectoryPath + '/default.realm',
schema: [dogsSchema],
readOnly: true,
});
const dogs = realm.objects('realm');
let resultArray = [];
const databaseRequest = () => {
const query = inputValue;
const result = inputValue
? dogs.filtered("name == '" + query + "'")
: 'default';
resultArray = Array.from(result);
return resultArray.map(dog => (
<Text className="dog" key={dog.name}>
{dog.name}
</Text>
));
};
//... until here
const isText = props.text;
return (
<View>
<Header searchBar rounded>
<Item>
<Icon name="ios-search" />
<Input
placeholder="Search"
onChangeText={text => sendInputValueToReduxStore(text)}
value={inputValue}
/>
</Item>
</Header>
<View>{databaseRequest()}</View>
</View>
);
};
function mapStateToProps(state) {
return {
inputValue: state.inputValue,
};
}
const mapDispatchToProps = {
setInputValueSearchBar,
};
export default connect(mapStateToProps, mapDispatchToProps)(SearchBar);
这和重构前的 Class Component 是同一个组件:
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {connect} from 'react-redux';
import {Header, Icon, Item, Input} from 'native-base';
import Realm from 'realm';
import fs from 'react-native-fs';
import {setInputValueSearchBar} from '../../../actions';
class SearchBar extends React.Component {
state = {
inputValue: null,
};
sendInputValueToReduxStore(text) {
this.setState({inputValue: text});
this.props.setInputValueSearchBar(text);
}
componentWillMount() {
const dogsSchema = {
name: 'realm',
properties: {
name: 'string?',
color: 'string?',
},
};
let realm = new Realm({
path: fs.DocumentDirectoryPath + '/default.realm',
schema: [dogsSchema],
readOnly: true,
});
const dogs = realm.objects('realm');
let resultArray = [];
this.databaseRequest = () => {
const query = this.state.inputValue;
const result = this.state.inputValue
? dogs.filtered("name == '" + query + "'")
: 'default';
resultArray = Array.from(result);
return resultArray.map(dog => (
<Text className="dog" key={dog.name}>
{dog.name}
</Text>
));
};
}
render() {
const isText = this.props.text;
return (
<View>
<Header searchBar rounded>
<Item>
<Icon name="ios-search" />
<Input
placeholder="Search"
onChangeText={text => this.sendInputValueToReduxStore(text)}
value={this.state.inputValue}
/>
</Item>
</Header>
{isText && (
<View>
<Text>{this.props.text}</Text>
</View>
)}
<View>{this.databaseRequest()}</View>
</View>
);
}
}
function mapStateToProps(state) {
return {
inputValue: state.inputValue,
};
}
const mapDispatchToProps = {
setInputValueSearchBar,
};
export default withNavigation(
connect(mapStateToProps, mapDispatchToProps)(SearchBar),
);
【问题讨论】:
-
将代码直接放在组件函数体中意味着它将在每次组件重新渲染时执行,请记住这一点
-
@David,但是 useEffect() 钩子不是在每次渲染时都执行吗?
-
@RuntimeError: 对
useEffect的调用本身会,但useEffect只会在您传递的依赖数组已更改时调用您传递的函数。
标签: reactjs react-native react-hooks