【问题标题】:React Native render from object从对象 React Native 渲染
【发布时间】:2021-04-17 07:31:24
【问题描述】:

我正在做一个简单的应用程序,我想在文本中呈现来自第二个 fecth 的结果,因此用户可以看到练习名称,但我可以同时记录两者,但我无法在文本中返回它。我试图将结果保存在状态变量中,但它执行了无限循环。

function UserPlan({route}) {
  const id = route.params.id;
  const token = route.params.token;
  //console.log(id, token);
 let myData ={}

  function getExercises() {
    fetch(`https://startdoing.herokuapp.com/user_plans/plan/${id}`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${token}`,
      },
    })
      .then((response) => response.json())
      .then((result) => {
        result.map((result) => {
          //console.log(result.exercises);
          result.exercises.map((data) => {
            //console.log(data.exercise_id);
            fetch(
              `https://startdoing.herokuapp.com/exercises/${data.exercise_id}`,
              {
                method: 'GET',
                headers: {
                  'Content-Type': 'application/json',
                  Authorization: `Bearer ${token}`,
                },
              },
            )
              .then((response) => response.json())
              .then((result) => {
                
                myData=result
                console.log(myData.exerciseName);
               /*  console.log(result);
                console.log(result.exerciseName);
                console.log(result.videoUrl); */
                
                
              })

              .catch((error) => console.log('error', error));
          });
        });
      })

      .catch((error) => console.log('error', error));
  }

  useEffect(() => {
    getExercises();
  });

  return(
     <>
     <Text>hello</Text>
     </>
  )
}

export default UserPlans;

【问题讨论】:

    标签: reactjs react-native return fetch render


    【解决方案1】:
        function UserPlan({route}) {
          const id = route.params.id;
          const token = route.params.token;
          //console.log(id, token);
         let myData ={}
         const [myExcerciseData, setExcerciseData] = useState(null)
    
        
          function getExercises() {
            fetch(`https://startdoing.herokuapp.com/user_plans/plan/${id}`, {
              method: 'GET',
              headers: {
                'Content-Type': 'application/json',
                Authorization: `Bearer ${token}`,
              },
            })
              .then((response) => response.json())
              .then((result) => {
                result.map((result) => {
                  //console.log(result.exercises);
                  result.exercises.map((data) => {
                    //console.log(data.exercise_id);
                    fetch(
                      `https://startdoing.herokuapp.com/exercises/${data.exercise_id}`,
                      {
                        method: 'GET',
                        headers: {
                          'Content-Type': 'application/json',
                          Authorization: `Bearer ${token}`,
                        },
                      },
                    )
                      .then((response) => response.json())
                      .then((result) => {
                        
                        myData=result
                        setExcerciseData(result)
                        console.log(myData.exerciseName);
                       /*  console.log(result);
                        console.log(result.exerciseName);
                        console.log(result.videoUrl); */
                        
                        
                      })
        
                      .catch((error) => console.log('error', error));
                  });
                });
              })
        
              .catch((error) => console.log('error', error));
          }
        
          useEffect(() => {
            getExercises();
          },[]); //if you pass variable here it will create infinite loop
    
           useEffect(() => {
            console.log("updated data")
          },[myExcerciseData]);
        
          return(
             <>
             {myExcerciseData ? 
              <Text>{myExcerciseData.exerciseName}</Text>
             :
             <Text>Loading...</Text>
             </>
          )
        }
        
        export default UserPlans;
    

    这应该可以,请检查一次,如果有任何问题,请恢复

    【讨论】:

    • 它仍在循环中
    • @clipshot 你能提供一个带代码的工作链接
    • 在这里。我硬编码了用户 ID 和令牌,所以你可以测试 codesandbox.io/s/wild-morning-dvphs?file=/src/App.js
    • @clipshot 获取无效令牌
    • 尝试此eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImVtYWlsIjoidGVzdGluZ0BlbWFpbC5jb20iLCJpZCI6IjVmZGQzYzZkOGE2YWNlMjg2MDE0MGUwYSIsIm5hbWUiOiJ0ZXN0aW5nIn0sImlhdCI6MTYwODU1MTY4NCwiZXhwIjoxNjE1NzUxNjg0fQ.mmzPDcRnXc5ZwZnZCasQ2l3705fLQcNZA9BMV5Cc9Fw 跨度>
    【解决方案2】:
    // If you want to fetch the first time only, add dependencies that makes your effect run again when changes.
    // In this case they are id and token
    
     const [exercises, setExercises] = useState([])
    
     useEffect(() => {
     function getExercises() {
        fetch(`https://startdoing.herokuapp.com/user_plans/plan/${id}`, {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${token}`,
          },
        })
          .then((response) => response.json())
          .then((result) => {
            result.map((result) => {
              
              Promise.all(result.exercises.map((data) => {
                
                return fetch(
                  `https://startdoing.herokuapp.com/exercises/${data.exercise_id}`,
                  {
                    method: 'GET',
                    headers: {
                      'Content-Type': 'application/json',
                      Authorization: `Bearer ${token}`,
                    },
                  },
                )
                  .then((response) => response.json())
                ).then((exercises) => {
       
                    setExercises(exercises)
                 })
                  
              });
            });
          })
    
          .catch((error) => console.log('error', error));
      }
    
    
        getExercises();
      }, [id, token]); // <-- Here
    

    阅读更多https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects

    【讨论】:

    • 是的,但是这种方式只返回最后一个值
    • 最后一个值是什么意思?你期待什么?
    • 例如,我知道现有的练习是俯卧撑和手臂弯举,如果我使用这种方法,它只会返回其中一个,我期望在视图中呈现两者,以便用户可以查看该计划中存在哪些练习
    • @clipshot:如果你想等待所有请求,你应该使用 Promise.all(...) => 将响应设置为状态。查看我的更新
    • 好的,问题已解决,但现在我有另一个问题。当我尝试渲染数组时,它只渲染第一个元素,但在 console.log 中我在数组中有 2 个元素!示例代码:` return ( {myExcerciseData.map((data) => { return ( {console.log(data.exerciseName)} 名称:{data.exerciseName} ) })} );`
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    相关资源
    最近更新 更多