programing

리액트 렌더 함수로 비동기화하는 방법

goodjava 2023. 3. 26. 11:20

리액트 렌더 함수로 비동기화하는 방법

저는 이 문제에 대해 잘 알고 있습니다.async await백엔드로nodejs그런데 프런트 엔드로 써야 하는 시나리오가 떠올랐어요.

오브젝트 어레이를 취득하고 그 오브젝트 내에서 취득하는lat lng그 장소들.현재 사용 중react-geocode나는 싱글의 장소 이름을 얻을 수 있다.lat lng지명을 얻기 위해 지도 안에 있는 것을 사용하고 싶습니다.우리가 알고 있는 바로는async사용해야 할 전화async await저기.

여기 코드가 있습니다.

import Geocode from "react-geocode";
render = async() => {
  const {
    phase,
    getCompanyUserRidesData
  } = this.props   
                      
  return (
    <div>
       <tbody>                   
        await Promise.all(_.get(this.props, 'getCompanyUserRidesData', []).map(async(userRides,index) => {
          const address = await Geocode.fromLatLng(22.685131,75.873468)
          console.log(address.results[0].formatted_address)                         
         return ( 
          <tr key={index}>
            <td>
            {address.results[0].formatted_address}
            </td>
            <td>Goa</td>
            <td>asdsad</td>
            <td>{_.get(userRides,'driverId.email', '')}</td>
            <td>{_.get(userRides,'driverId.mobile', '')}</td>
          </tr>
        )
        }))
      </tbody>
    </div>
  )
}

그러나 여기서 지도 기능과 함께 비동기 기능을 사용해도 아무것도 반환되지 않습니다.제가 잘못하는 곳을 누가 좀 도와주실 수 있나요?

항상 데이터 가져오기 등의 문제와 표시와 같은 문제를 분리해야 합니다.여기에는 AJAX를 통해 데이터를 가져온 다음 데이터가 들어오면 조건부로 기능하는 하위 구성 요소를 렌더링하는 상위 구성 요소가 있습니다.

class ParentThatFetches extends React.Component {
  constructor () {
    this.state = {};
  }

  componentDidMount () {
    fetch('/some/async/data')
      .then(resp => resp.json())
      .then(data => this.setState({data}));
  }

  render () {
    {this.state.data && (
      <Child data={this.state.data} />
    )}
  }
}

const Child = ({data}) => (
  <tr>
    {data.map((x, i) => (<td key={i}>{x}</td>))}
  </tr>
);

실제로 실행하지 않았기 때문에 사소한 오류가 있을 수 있으며 데이터 레코드에 고유한 ID가 있는 경우 어레이 인덱스 대신 키 속성에 ID를 사용해야 합니다.

갱신하다

후크를 사용하면 동일하지만 후크를 사용하여 보다 단순하고 간단하게 사용할 수 있습니다.

const ParentThatFetches = () => {
  const [data, updateData] = useState();
  useEffect(() => {
    const getData = async () => {
      const resp = await fetch('some/url');
      const json = await resp.json()
      updateData(json);
    }
    getData();
  }, []);

  return data && <Child data={data} />
}

아래 래퍼 함수 delayed_render()를 사용하면 React 컴포넌트 함수 내에 비동기 코드를 쓸 수 있습니다.

function delayed_render(async_fun, deps=[]) {
    const [output, setOutput] = useState()
    useEffect(async () => setOutput(await async_fun()), deps)
    return (output === undefined) ? null : output
}

이 래퍼는 지연 렌더링을 수행합니다. 반환됩니다.null초기 렌더링 시도 시(이 특정 컴포넌트의 렌더링을 건너뛰기 위해)는 주어진 렌더링 출력을 통해 적절한 렌더링 출력을 비동기적으로 계산합니다(useEffect()).async_fun()재렌더링을 호출하여 최종 결과를 DOM에 주입합니다.이 래퍼는 다음과 같이 간단하게 사용할 수 있습니다.

function Component(props) {
    return delayed_render(async () => { /* any rendering code with awaits... */ })
}

예를 들어 다음과 같습니다.

function Component(props) {
    return delayed_render(async () => {
        const resp = await fetch(props.targetURL)     // await here is OK!
        const json = await resp.json()
        return <Child data={json} />
    })
}

업데이트: 추가deps논쟁.만약 당신이async_fun소품 또는 상태 변수에 따라 모든 변수가 에 나열되어야 합니다.deps재접속을 가능하게 합니다.주의: 통과에 주의해 주세요.deps=null(항상 재접속)은 여기서 선택사항이 아닙니다.output또한 상태 변수이며 종속성에 암묵적으로 포함되며, 이로 인해 데이터 처리 후 무한 재검출이 발생합니다.async_fun콜이 완료됩니다.

이 솔루션은 Jared Smith의 솔루션에서 영감을 얻어 일반화한 것입니다.

언급URL : https://stackoverflow.com/questions/53819864/how-to-async-await-in-react-render-function