Bagaimana cara menggabungkan item ke array terakhir di dalam array root?

Pada dasarnya, ketika saya menekan sebuah tombol, fungsi saya akan mulai mendengarkan perubahan koordinat dan menggabungkan data yang baru dikumpulkan ke dalam array.

Saat tombol ditekan lagi, pendengar akan dikeluarkan. Pengguna dapat menekan tombol dan mulai mendengarkan kumpulan koordinat baru lagi. Mereka dapat melakukan hal ini berulang kali.

this.state = {
    pathArray: [], // originally a 1D array, should become 2D as user keep using the app
    pathCount: 0,
}

Seperti inilah tampilan array terakhir sehingga saya dapat melanjutkan ke bagian rendering. Saya ingin dapat secara dinamis membuat indeks baru dalam array sehingga data baru akan dimasukkan ke bagian bawah daftar.

Bagaimana saya bisa membuat array baru di dalam array root ketika tombol ditekan, dan terus menambahkan objek ke dalam array anak sampai tombol ditekan lagi. Jika tombol ini ditekan lagi, array anak baru akan dibuat lagi, dan prosesnya terus berjalan.

pathArray = [
    [ 
        { lat: 0, long: 0 },
        { lat: 1, long: 2 },
    ],
    [ 
        { lat: 0, long: 0 },
        { lat: 1, long: 2 },
    ],
]

onButtonPressed = () => {
    const { running } = this.state
    if (!this.state.running) {
      this.followWatchCoords() // start collecting data
    } else {
      this.stopFollowing() //stop collecting data
    }
  }

followWatchCoords = () => {
    this.followUserWatchID = navigator.geolocation.watchPosition(({ coords }) => {
    
      this.calculateDistance(coords)

    }, null, GEOLOCATION_SETTINGS)
  }

calculateDistance = (coords) => {
    const { latitude, longitude } = coords

    const positionLatLong = pick(coords, ['latitude', 'longitude'])

    let newArr = this.state.pathArray.slice(); //copy array to mutate
    newArr.push(positionLatLong)


    this.setState({
      pathArray: newArr,
    })
  }


person J.Doe    schedule 30.05.2017    source sumber
comment
Jadi apa pertanyaannya?   -  person Chris    schedule 30.05.2017
comment
Bagaimana saya bisa membuat array baru di dalam array root ketika tombol ditekan, dan terus menambahkan objek ke dalam array anak sampai tombol ditekan lagi. Jika tombol ini ditekan lagi, array anak baru akan dibuat lagi, dan prosesnya terus berjalan.   -  person J.Doe    schedule 30.05.2017
comment
Apakah tombol ini memicu proses berulang dimana entri dilakukan setiap X detik hingga tombol ditekan kembali?   -  person Chris    schedule 30.05.2017
comment
pada dasarnya, tombol tersebut memicu fungsi lain (pendengar GPS) dan di sinilah saya memanipulasi array. Ya, Anda mengerti @Chris   -  person J.Doe    schedule 30.05.2017
comment
Untuk membuat array baru di akhir daftar: pathArray.push([]). Untuk menambahkan elemen dalam array yang baru dibuat ini: pathArray[pathArray.length - 1].push({lat: 1, long: 2}).   -  person abhishekkannojia    schedule 30.05.2017
comment
@abhishekkannojia reactjs tidak mengizinkan saya melakukan pathArray[pathArray] di blok setState...   -  person J.Doe    schedule 30.05.2017


Jawaban (2)


Di bawah ini cuplikan sederhana tentang bagaimana Anda dapat menerapkannya.

Pada dasarnya urutan kejadiannya adalah:

  1. Mengklik tombol memicu fungsi _startStop() yang memulai suatu interval.
  2. Interval mengambil koordinat lintang/bujur dari API GPS palsu setiap 3000 ms.
  3. Koordinat baru dimasukkan ke dalam array negara bagian.

Jika Anda mengklik tombol itu lagi, fungsi yang sama akan dipicu, tetapi intervalnya dihapus dan proses dihentikan.

class MyApp extends React.Component {
  constructor() {
    super();
    this.interval;
    this.state = {arr: []};
    this._getFakeCoords = this._getFakeCoords.bind(this);
    this._startStop = this._startStop.bind(this);
  }
  
  _getFakeCoords() {   
    return {lat: Math.random() * 100, long: Math.random() * 100};
  }
  
  _startStop() {
    if(this.interval) {
      clearInterval(this.interval);
      this.interval = null;
    } else {
      let newArr = this.state.arr.slice();  //copy the array so we can mutate it
      this.interval = setInterval(() => {
        newArr.push([this._getFakeCoords(), this._getFakeCoords()]);
        this.setState({arr: newArr});  //replace the old array with the mutated one
        console.log(newArr);  //preview the result
      }, 3000);
    }
  }
  
  render() {
    return (
      <div>
      	<button onClick={this._startStop}>Start/Stop</button>
      </div>
    );
  }
}

ReactDOM.render(<MyApp />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

person Chris    schedule 30.05.2017
comment
Tampaknya bisa dilakukan tetapi 2 hal. Pertama, perpustakaan geolokasi merilis data baru setiap beberapa milidetik, sehingga fungsi setInterval mungkin tidak akan berguna di sini. Komponen yang saya gunakan untuk merender garis membutuhkan 1 array objek untuk merender 1 baris. 2 objek = 1 baris, banyak objek (dalam 1 array) = 1 garis yang sangat panjang. Jadi idealnya, jika pathArray saya memiliki 2 array anak, maka kita mengharapkan 2 baris. - person J.Doe; 30.05.2017
comment
Baru saja mencoba pendekatan Anda tetapi tidak sesuai dengan kebutuhan saya haha, izinkan saya memperbarui postingan saya dengan kode saya saat ini - person J.Doe; 30.05.2017
comment
@J.Doe, oke, tapi ini hanya bukti konsep. Bukan solusi yang lengkap. Jika API Anda bekerja secara berbeda, ubah saja kodenya. Saya kira pertanyaannya di sini adalah bagaimana cara mengonversi array atau apa pun. Perbarui saja bagian itu - yaitu tampilan array pada awalnya, dan seperti apa hasilnya. Saya hanya akan memperbarui bagian itu. - person Chris; 30.05.2017
comment
Saya telah memperbarui postingan dengan kode saya, seperti yang Anda lihat fungsi hitung Jarak akan diperbarui setiap kali perpustakaan geolokasi mengumpulkan data baru. - person J.Doe; 30.05.2017
comment
@J.Doe, oke. Saya tidak melihat bagian dengan masalah array 1D -› 2D. Itulah masalahnya di sini, kan? - person Chris; 30.05.2017
comment
Haha kawan, calculDistance mungkin akan dieksekusi ribuan kali untuk setiap sesi tombol. Trik untuk masalah ini adalah data baru akan selalu ditambahkan ke daftar paling bawah. Jadi mungkin kita bisa membuat array kosong saat tombol pertama kali ditekan, lalu menambahkan data ke anak terakhir array?? hmmm - person J.Doe; 30.05.2017
comment
@ J.Doe Anda menjelaskan masalah Anda dengan buruk dan Anda memiliki banyak kode yang tidak relevan dengan masalah pemrograman yang Anda tanyakan. Ini menyulitkan orang lain untuk mengikutinya karena Anda menjelaskan keseluruhan aplikasi Anda daripada masalah spesifiknya... lagi pula, jika saya memahaminya dengan benar, Anda mungkin bisa menggunakan dua larik - satu untuk pathArray dan lainnya tempArray. tempArray mulai terisi dengan koordinat ketika Anda mengklik tombol untuk memulai, dan ketika Anda berhenti, Anda menekan tempArray ke dalam pathArray? - person Chris; 30.05.2017
comment
Saya menerima kritik Anda dan akan mengatasi masalah pengiriman saya. Komponen saya harus mengakses childArray terakhir secara real time. Jadi jika kita memasukkan tempArray ke pathArray hanya setelah tombol ditekan lagi, maka intinya akan hilang karena aplikasi saya perlu menggambar jalur secara real time :( - person J.Doe; 30.05.2017
comment
logikanya tampaknya benar tetapi ketika saya mendorong array baru ia mengembalikan indeks 1, lalu saya mencoba memasukkan data ke dalam array itu menunjukkan 'Tidak dapat membaca properti 'push' yang tidak terdefinisi' - person J.Doe; 30.05.2017
comment
Mari kita melanjutkan diskusi ini dalam chat. - person Chris; 30.05.2017

Akhirnya beres setelah beberapa saran berguna yang diberikan oleh Chris

Dalam fungsi tombol saya, saya membuat array anak baru setiap kali dipanggil

this.setState({
    routeCoordinates: this.state.routeCoordinates.concat([[]]), //add array
    routeCount: this.state.routeCount + 1
})

juga menambah RouteCount sebanyak satu setiap kali tombol ditekan (awalnya -1 karena sifat array)

Kemudian pada GPS Listener, karena fungsi hitung Jarak akan dipanggil setiap ada data baru yang masuk maka kita hanya perlu melakukan hal berikut

let newArr = [...routeCoordinates]
newArr[routeCount].push(positionLatLong)

this.setState({ routeCoordinates: newArr })

Caranya adalah dengan menggunakan concat dan push dengan bijak

person J.Doe    schedule 30.05.2017
comment
Senang Anda menemukan solusinya. Anda harus menerima jawaban Anda sendiri, dan mempertimbangkan untuk memberi suara positif pada jawaban saya jika menurut Anda itu berguna. Terima kasih. - person Chris; 31.05.2017
comment
Tentu! Akan menerima jawaban saya setelah 2 hari (kendala SO) - person J.Doe; 31.05.2017