Ожидаемое поведение : два рендера. Первоначально вы видите загрузчик, и когда студенты успешно выбираются в фоновом режиме, загрузчик изменяется на список, который заполнен студентами.
Что я пропускаю?
Начальный рендер
использовать состояние, чтобы установить elem
для отображения (<Loader/>
) и массив students
(один начальный объект для тесты)
выборка students
массив объектов в useEffect
при успешном обновлении состояния выборки - установите students
в выбранный массив и от elem
до renderList
, которые будут заполнять элементы списка с students
содержимым
console.log(students.length)
показывает 1 в этот момент - правильно
состояние обновлено, поэтому повторное отображение
Второй рендер
console.log(students.length)
показывает 49 -
students
правильно обновлено
ПОЧЕМУ? - 7. renderList
видит начальное значение students
(1 объект)
Это потому, что отображаемый elem
и его содержимое (students
) находятся в состоянии, и они оба обновляются в useEffect
одновременно?
<!-- language: lang-js -->
all imports
export default function AttendanceSingleClass(props) {
const {classId, groupId} = props.route.params.classObj;
const [students, _setStudents] = useState([{sId:1,name:'foo',fname:'bar'}]);
const [elem, _setElem] = useState(<Loader/>);
useEffect(() => {
async function _getStudentsList() {
try {
const students = await api.getStudentsList(groupId, classId);
_setStudents(students);
_setElem(renderList)
} catch (e) {
console.log(e)
}
}
_getStudentsList();
},[classId]);
const ListEl = (props) => {
return (
<View>..contents of list item...</View>
)
}
const renderList = () => {
return (
<View>
<FlatList
data={students}
extraData={students}
keyExtractor={item => item.sId}
renderItem={({item}) => <ListEl item={item} />}
/>
</View>
);
}
console.log(students.length);
return elem;
}
после некоторых экспериментов Я попытался передать массив students
как prop
в renderList
- работает. Но все же я не понимаю, почему он видит students
в глобальной области видимости, но только в начальном значении, а не в обновленном состоянии (как показано выше).
<!-- language: lang-js -->
export default function AttendanceSingleClass(props) {
(...)
useEffect(() => {
async function _getStudentsList() {
try {
_setElem(renderList(students))
}
}
_getStudentsList();
}, [classId]);
const renderList = (students) => {
return (...);
}
(...);
}