6

나는이 시점에서 내가 Reactive Native에 대해 아주 처음이다. 그래서 나는 이것이 쉬운 대답이되고 잠재적으로 어리석은 질문이 될 것이라고 전적으로 인정한다. 사실, 이것은 아래에서 설명 할 것처럼 RN 문제 그 자체입니다.Reactive 네이티브 FlatList에 데이터로드

class MyScreen extends React.Component { 

    constructor(inProps) { 
    super(inProps); 
    this.state = { listData : [ ] }; 
    } 

    render() { return (
    <View> 
     <FlatList data={ this.state.listData } 
     renderItem={ ({item}) => 
      <Text>{item.firstName} {item.lastName}</Text> 
     } 
     /> 
    </View> 
); } 

    async componentDidMount() { 
    const data = [ ]; 
    let keys = await AsyncStorage.getAllKeys(); 
    keys.forEach(async function(inKey) { 
     let obj = await AsyncStorage.getItem(inKey); 
     obj = JSON.parse(obj); 
     data.push(obj); 
    }); 
    this.setState({ listData : data }); 
    }; 

} 

목표는 AsyncStorage에서 데이터를로드하고 목록에서 덤프하는 것입니다 :

는 내가 가지고하면 다음과 같은 코드입니다. 상당히 기본적인 것 같아요, 그렇죠? 불행히도, 나는 그것을 작동시킬 수 없습니다 : 목록은 비어 있습니다.

바보 같은 것들을 다룰 때 : 네, 참으로 데이터가 저장되어 있습니다. 올바른 형식입니다. (나는 이것을 알고 있습니다. 단순히 하나의 특정 항목을 잡고 데이터로 푸시하면됩니다.) 예상대로 목록).

는 사실, 문제가 무엇인지 알고 그것을 keys.forEach() 호출이 완료되기 전에 setState를() 호출이 실행되어 있습니다. 예상대로

setTimeout(function() { 
    this.setState({ listData : data }); 
}.bind(this), 1000); 

... 갑자기 내 목록이 채워집니다 (나는 또한 거기에) (의 일부 CONSOLE.LOG을 던져 볼 수 있습니다 : 나는)합니다 (setState를 교체하는 경우이 콜 때문에 나는 이것을 알고 keys.forEach()를 호출 한 후에 실제로 keys.forEach 내부보다 먼저 실행하는()). 나는 또한 분명히 준 getItem() 호출 그렇지 않으면이 전혀 작동하지 않을 것,()가 호출 된 JSON.parse 전에 기다리고 있음을 알고있다. 즉

:이 알고는이 코드의 비동기 특성에 기인한다. 내가 알아낼 수없는 것은 이것을 피하기 위해 올바르게 쓰는 방법이다.

나는 그것을보고 있는데, "keys.forEach()는 블로킹 호출이므로 setState() 호출 전에는 어떻게 완료되지 않았을까? 특히 비동기 사용법이 키에 주어진다. .forEach() 콜백 및 getItem() 호출에서 사용을 기다리고 있나? "... 유일한 생각은 keys.forEach() 호출 앞에 비동기를 드롭하는 것이지만 아무런 차이가 없습니다. .

그래서, 본질적으로 기본적인 자바 스크립트 질문 것으로 보인다,하지만 난 그것을 해결하기 위해 수없는 것 ...하지만 다른 한편으로는, 나는 나는이 작업을 수행하기 위해 노력하고있어 잘 모르겠어요 나는 근본적으로 RN 땅에 안 어쩌면 그게 진짜 문제는 웨이.

응용 프로그램을 통한 흐름 (다른 화면에서 추가)으로 인해 AsyncStorage에서 데이터를 동적으로 가져와야하므로 componentDidMount()에서로드하려고하면 나에게 맞는 것처럼 보입니다. 관련된 호출의 비동기 성질에 매달려 있습니다.

제안 사항?

감사합니다.

편집 :이 문제를 해결할 수있는 방법 중 하나는 개별 데이터 항목을 저장하는 대신 비동기 성을 완전히 제거하는 것임을 알리고 AsyncStorage의 모든 개체를 하나의 개체에 저장하는 것입니다. 그럼 하나의 항목을 읽을 수있는 배열 (또는 배열을 포함), 다음 비동기 부분은 getItem() 호출하지만, 그 콜백 버전을 사용할 수있는 그런 식으로 작동합니다 .. .나는 전혀 그 접근 방식에 대해 모르겠지만,이 시점에서 정말 일을해야처럼 :)이 것 때문에 다른 이유 뭔가를 배울 것보다 만약 내가 잘못 이해하려는

+0

슈퍼 : 당신이 정말로 forEach를 원하는 경우

for (let inKey of keys) { let obj = await AsyncStorage.getItem(inKey); obj = JSON.parse(obj); data.push(obj); } 

하면, 당신은 당신이 예를 들어 그것을 await를 연결할 수 있도록 Promise을 돌려 자신의 버전을 작성해야 해키 방법은 ... {data.length> 1? this.setState ({listData : data}) : emptylist} ... 또한 data.push (obj) 바로 다음에 setState를 이동할 수 있습니까? 데이터를 다시 작성한다는 의미에서 비효율적 일뿐만 아니라 오류가 발생해도 데이터를 확보 할 수 있습니까? Async Await은 내게 새롭기 때문에, 게시 해 주셔서 감사합니다. 이것은 goooooooood 반응 질문입니다. –

답변

3

keys.forEach은 자신의 범위 (자체 콜백 함수)에서 코드를 실행하며 이는 async/await 쌍을 나눕니다.

대신이 작업을 수행 :

await keys.awaitableForEach(async function(inKey) { 
+0

완벽하게 보입니다. 고마워요! 어쨌든 더 효율적이기 때문에 궁극적으로 단일 객체 접근 방식을 사용하려고합니다.하지만 적어도 이제는 문제가 발생한 이유를 이해합니다. 각자 실현하지 못했습니다. 각각 비동기/대기 쌍을 깨뜨릴 것입니다. 내가 각자를 위해 사용할 필요가 있었던 어떤 특별한 이유도 마음에 처음으로 나온 것이었다. –