Работая над приложением для Android с использованием React Native, я наткнулся на странную проблему.
Для поиска по базе данных существует панель поиска. Результат должен быть представлен. В приведенном ниже коде вы видите, что я установил переменную с результатом в useEffect()
-Крюк после определения переменной снаружи с помощью useRef()
: let returnValue = useRef('No results');
Так что я ожидал, что если я наберу имя, такой как «Майк», результат базы данных (сохраненный в returnValue.current
) будет отображен сразу после отправки.
Но нет.
На самом деле, результат "Mike" отображается после того, как я снова открываю панель поиска и удаляю последний символ, оставляя "Mik". Затем приложение отображает «Майк», как если бы оно было точно на шаг позади.
После поиска проблемы я только что обнаружил asyn c «проблемы» с useState()
-Крючком, но не с useEffect()
. Когда я делаю console.log()
useState()
, все настроено правильно. Даже внутри useEffect()
- регистрация returnValue.current
всегда дает правильный результат в правильное время. Единственная проблема - рендеринг returnValue.current
с такой странной задержкой.
Кто-то может демистифицировать это поведение?
import ...
const SearchBar = props => {
let [inputValue, setInputValue] = useState(null);
let returnValue = useRef('No results');
const sendInputValueToReduxStore = text => {
setInputValue(text);
props.setInputValueSearchBar(text);
};
useEffect(() => {
// setting database schema
const personsSchema = {
name: 'realm',
properties: {
name: 'string?',
color: 'string?',
},
};
// open the database
let database = new Realm({
path: fs.DocumentDirectoryPath + '/default.realm',
schema: [personsSchema ],
readOnly: true,
});
// doing the database query
const allPersons = database.objects('realm');
let resultArray = [];
const query = inputValue;
const queryResult = inputValue
? allPersons.filtered("name == '" + query + "'")
: 'default';
resultArray = Array.from(queryResult);
const personNamesArray = resultArray.map(value => value.name);
const personNames = personNamesArray.toString();
returnValue.current = personNames;
// logging always correct
console.log('person name: ', personNames);
}, [inputValue]);
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>
{isText && (
<View>
<Text>{props.text}</Text>
</View>
)}
//returnValue.current is rendered with delay
{returnValue && <Text>{returnValue.current}</Text>}
</View>
);
};