首页 > 解决方案 > 如何将回调函数参数传递给父反应组件?

问题描述

只是想知道将 letterSelected 传递给 useLazyQuery fetchMovies 查询的最佳方法,这样我就不必使用“A”的静态变量。我希望有一种方法可以将它直接传递给 fetchMovies。useLazyQuery 是一个阿波罗查询。

const BrowseMovies = () => {

const [fetchMovies, { data, loading}] = useLazyQuery(BROWSE_MOVIES_BY_LETTER, {
    variables: {
        firstLetter: "A"
    }
})

return (
    <div className="browserWrapper">
        <h2>Browse Movies</h2>
        <AlphabetSelect 
            pushLetterToParent={fetchMovies}
        />
        {
            data && !loading &&
            data.browseMovies.map((movie: any) => {
                return (
                    <div className="browseRow">
                        <a className="movieTitle">
                            {movie.name}
                        </a>
                    </div>
                )
            })
        }
    </div>
)
}

export default BrowseMovies

const AlphabetSelect = ({pushLetterToParent}: any) => {

const letters = ['A','B','C','D','E','F','G','H','I','J','K','L', 'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','#']

const [selectedLetter, setSelectedLetter] = useState("A")

const onLetterSelect = (letter: string) => {
    setSelectedLetter(letter.toUpperCase())
    pushLetterToParent(letter.toUpperCase())
}

return (
    <div className="alphabetSelect">
        {
            letters.map((letter: string) => {
                return(
                    <div 
                        className={selectedLetter === letter ? 'letterSelectActive' : 'letterSelect'} 
                        onClick={() => onLetterSelect(letter)}
                    >
                        {letter}
                    </div>
                )
            })
        }
    </div>
)
}
export default AlphabetSelect

标签: javascriptreactjsapollo

解决方案


这似乎是Lifting State Up解决的问题。useLazyQuery接受一个 gql 查询和选项,并返回一个函数以在以后执行查询。听起来您希望子组件更新variables配置参数。

浏览电影

  1. 移动firstLetter状态BrowseMovies组件

  2. 从状态更新查询参数/选项/配置

  3. 添加useEffect以在状态更新时触发获取

  4. firstLetter将状态和状态更新器传递setFirstLetter给子组件

    const BrowseMovies = () => {
      const [firstLetter, setFirstLetter] = useState('');
    
      const [fetchMovies, { data, loading}] = useLazyQuery(
        BROWSE_MOVIES_BY_LETTER,
        { variables: { firstLetter } } // <-- pass firstLetter state
      );
    
      useEffect(() => {
        if (firstLetter) {
          fetchMovies(); // <-- invoke fetch on state update
        }
      }, [firstLetter]);
    
      return (
        <div className="browserWrapper">
          <h2>Browse Movies</h2>
          <AlphabetSelect 
            pushLetterToParent={setFirstLetter} // <-- pass state updater
            selectedLetter={firstLetter} // <-- pass state
          />
          {
            data && !loading &&
              data.browseMovies.map((movie: any, index: number) => {
                return (
                  <div key={index} className="browseRow">
                    <a className="movieTitle">
                      {movie.name}
                    </a>
                  </div>
                )
              })
          }
        </div>
      )
    }
    

字母选择

  1. pushLetterToParent回调附加到divonClick处理程序

     const AlphabetSelect = ({ pushLetterToParent, selectedLetter }: any) => {
    
       const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ#';
    
       return (
         <div className="alphabetSelect">
           {
             letters.split('').map((letter: string) => {
               return(
                 <div
                   key={letter}
                   className={selectedLetter === letter ? 'letterSelectActive' : 'letterSelect'} 
                   onClick={() => pushLetterToParent(letter.toUpperCase())}
                 >
                   {letter}
                 </div>
               )
             })
           }
         </div>
       )
     }
    

推荐阅读