簡體   English   中英

使用 react 獲取數組中的下一個/上一個項目

[英]get next Next/Previous item in array using react

我是反應和編程的新手,我已經搜索過並且只找到了 js 的解決方案,而不是特定於反應的。

在通過 props 傳遞的數組中顯示下一個或上一個項目時遇到問題。 單擊“下一步”按鈕時,我只看到數組中的同一個項目被返回而不是下一個項目,我知道上一個將返回 null 作為加載時顯示的第一個項目。

import React, { Component } from 'react'
import VideoPlayer from './Video'
import axios from 'axios'

export default class App extends Component {
constructor(props) {
super(props);

this._TogglePrev = this._TogglePrev.bind(this);
this._ToggleNext = this._ToggleNext.bind(this);

// app state
this.state = {
videos: [],
selectedVideo: null
 }
}

componentDidMount() {
   axios.get('http://localhost:5000/v1/video?id=287948764917205')
   .then((result)=> {
     var videos = result.data.payload
     this.setState({
       videos: videos,
       selectedVideo: videos[0]
     });
   })
 }

componentWillUnmount() {
 this.serverRequest.abort()
 }

// State transitions
  _ToggleNext() {
    console.log("something worked");
    // take a copy of our state
    const selectedVideo = this.state.selectedVideo;
    // next video
    var i = 0,
    max = selectedVideo.length;
    for (i; i < max; i += 1) {
        if (selectedVideo[i]) {
            return selectedVideo[i + 1];
        }
    }
    //set our state
    this.setState( selectedVideo );
    console.log(selectedVideo)
  }

  _TogglePrev() {
    console.log("something worked");
    var current = this.state.selectedVideo;
    var prev = current - 1;
    if (prev < 0) {
      prev = this.state.videos.length - 1;
    }
    // update our state
    this.setState({ prev });
  }

 render() {
  return (
     <div className="App" style={{width: '100%', height: '100%'}}>
       <div className="controls">
         <button className="toggle toggle--prev" onClick={this._TogglePrev}>Prev</button>
         <button className="toggle toggle--next" onClick={this._ToggleNext}>Next</button>
       </div>
        <VideoPlayer video={this.state.selectedVideo} />
     </div>
  )
 }
}

返回的數據

[
 {  eventId: "287948764917205"
  userName: "Jon Doe"
  videoLink: "https://"https:s3.amazonaws.com/...""
  userPhotoLink: "https://"https:s3.amazonaws.com/...""
 },
 { eventId: "287948764917205"
 userName: "Jane Thompson"
 videoLink: "https://"https:s3.amazonaws.com/...""
 userPhotoLink: "https://"https:s3.amazonaws.com/...""
 }  
]

錯誤:

1.如果在for循環中使用return關鍵字,則不僅會中斷loop ,還會從該函數返回,因此在這些行中:

for (i; i < max; i += 1) {
    if (selectedVideo[i]) {
        return selectedVideo[i + 1];
    }
}
this.setState( selectedVideo );
....

如果if(selectedVideo[i])返回true,則它將中斷循環並從函數返回,因此由於該return語句,此for循環之后的行將永遠不會執行。

2. setState是一個函數,我們需要在其中傳遞一個object (鍵-值對,鍵將是狀態變量名稱),因此您需要這樣編寫:

this.setState({ selectedVideo }); or this.setState({ selectedVideo: selectedVideo });  //both are same

通過維護索引來編寫代碼的另一種方式

1.而不是在狀態變量中維護selectedVideo ,而是僅維護索引,即數組項的索引。

2.單擊“下一步”和“上一個”按鈕時,增大或減小索引的值,然后使用該索引將狀態視頻數組的特定對象傳遞給子組件。

像這樣:

import React, { Component } from 'react'
import VideoPlayer from './Video'
import axios from 'axios'

export default class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            videos: [],
            selectedIndex: 0
        }
        this._TogglePrev = this._TogglePrev.bind(this);
        this._ToggleNext = this._ToggleNext.bind(this);
    }

    componentDidMount() {
        axios.get('http://localhost:5000/v1/video?id=287948764917205')
        .then((result)=> {
            var videos = result.data.payload
            this.setState({
                videos: videos,
                selectedIndex: 0
            });
        })
    }

    componentWillUnmount() {
        this.serverRequest.abort()
    }

    _ToggleNext() {
        if(this.state.selectedIndex == this.state.videos.length - 1)
            return;

        this.setState(prevState => ({
            selectedIndex: prevState.selectedIndex + 1
        }))
    }

    _TogglePrev() {
        if(this.state.selectedIndex == 0)
         return;

        this.setState(prevState => ({
            selectedIndex: prevState.selectedIndex - 1
        }))
    }

    render() {
        let {selectedIndex, videos} = this.state;
        return (
             <div className="App" style={{width: '100%', height: '100%'}}>
                  <div className="controls">
                    <button className="toggle toggle--prev" onClick={this._TogglePrev}>Prev</button>
                    <button className="toggle toggle--next" onClick={this._ToggleNext}>Next</button>
                  </div>
                  <VideoPlayer video={videos[selectedIndex]} />
             </div>
        )
    }
}

使用document.activeElement來獲取當前聚焦的元素。 然后,使用nextElementSibling on order 獲取下一個元素然后focus()就像這個document.activeElement.nextElementSibling.focus()

  • 完整示例
export default function TextField() {
    return (
        <div
        onKeyDown={(e:any)=>{
            if (e.keyCode==13){
                const active:any = document.activeElement
                active.nextElementSibling.focus()
            }
        }}
        >
            <input/>
            <input/>
            <input/>
        </div>
    );
};

最好在構造函數中編寫:

    constructor(props) {
    super(props);

    this._TogglePrev.bind(this);
    this._ToggleNext.bind(this);

    // app state
    this.state = {
    videos: [],
    selectedVideo: null,
selectedVideoIndex:0
     }
    }

並且也改變

 _ToggleNext() {
    console.log("something worked");
    // take a copy of our state
    const selectedVideo = this.state.selectedVideo;
    // next video
    var selectedVideoIndex = this.state.selectedVideoIndex; //i always starts with zero ????? you need also to save the index

    max = selectedVideo.length;
    for (selectedVideoIndex; selectedVideoIndex < max; selectedVideoIndex++) {
        if (selectedVideo[selectedVideoIndex]) {
            const retval = selectedVideo[selectedVideoIndex + 1];
            this.setState( selectedVideoIndex+1 );
            this.setState(retval  );
            return retval;
        }
    }


    console.log(selectedVideo)
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM