Form öğesi durumunu kardeş / üst öğelere geçirmenin doğru yolu nedir?


186
  • C1 ve C2 olmak üzere iki alt sınıf oluşturan bir React sınıfına sahip olduğumu varsayalım.
  • C1 bir giriş alanı içerir. Bu girdi alanına Foo diyeceğim.
  • Amacım C2'nin Foo'daki değişikliklere tepki vermesine izin vermek.

İki çözüm buldum, ama ikisi de oldukça iyi hissettirmiyor.

İlk çözüm:

  1. P'ye bir durum atayın state.input.
  2. onChangeP'de bir olayı alan ve ayarlayan bir işlev oluşturun state.input.
  3. Bu geçmek onChangebir şekilde C1 propsve C1 bağlama izin this.props.onChangeiçin onChangeFoo.

Bu çalışıyor. Foo'nun değeri her değiştiğinde setStateP'de a'yı tetikler , bu nedenle P'nin C2'ye geçmek için girişi olacaktır.

Ama aynı nedenden ötürü pek doğru gelmiyor: Bir üst öğenin durumunu alt öğeden ayarlıyorum. Bu, React'in tasarım prensibine ihanet ediyor gibi görünüyor: tek yönlü veri akışı.
Bunu böyle mi yapmam gerekiyor, yoksa daha doğal bir çözüm var mı?

İkinci çözüm:

Foo'yu P'ye koy.

Ancak bu, uygulamamı yapılandırırken izlemem gereken bir tasarım ilkesi mi - tüm form öğelerini renderen üst düzey sınıfın içine yerleştiriyor mu?

Ben C1 büyük bir render varsa benim örnekte olduğu gibi, ben gerçekten bütün koymak istemiyorum renderiçin C1 renderC1 bir form öğesi var diye, P.

Bunu nasıl yapmalıyım?


Tam olarak aynı şeyi yapmak üzereyim ve düzgün çalışmasına rağmen, bunun sadece dev bir hack olduğunu hissediyorum
Mirko

Yanıtlar:


198

Sizi doğru anlıyorsam, ilk çözümünüz kök bileşeninizde durumu korumanızı mı önerir? React'in yaratıcıları için konuşamam, ancak genellikle bunun uygun bir çözüm olduğunu düşünüyorum.

Durumu korumak, React'ın yaratılmasının nedenlerinden biridir (en azından bence). Çok sayıda birbirine bağlı hareketli parçası olan dinamik bir kullanıcı arayüzüyle uğraşmak için kendi durum kalıbı istemci tarafınızı uyguladıysanız, React'i seveceksiniz, çünkü bu durum yönetimi ağrısının çoğunu hafifletir.

Durumu hiyerarşide daha yukarıda tutarak ve olay yoluyla güncelleyerek veri akışınız hala tek yönlüdür, sadece Kök bileşenindeki olaylara yanıt veriyorsunuz, verileri gerçekten iki yönlü bağlamayla elde etmiyorsunuz, Kök bileşenine "hey, burada bir şey oldu, değerleri kontrol edin" diyorsunuz veya durumu güncellemek için alt bileşendeki bazı verilerin durumunu geçiyorsunuz. C1'deki durumu değiştirdiniz ve C2'nin bunun farkında olmasını istiyorsunuz, bu nedenle, Kök bileşenindeki durumu güncelleyerek ve yeniden render ederek, durum Kök bileşeninde güncellendiği ve aktarıldığı için C2'nin sahne ayarları artık senkronize durumda .

class Example extends React.Component {
  constructor (props) {
    super(props)
    this.state = { data: 'test' }
  }
  render () {
    return (
      <div>
        <C1 onUpdate={this.onUpdate.bind(this)}/>
        <C2 data={this.state.data}/>
      </div>
    )
  }
  onUpdate (data) { this.setState({ data }) }
}

class C1 extends React.Component {
    render () {
      return (
        <div>
          <input type='text' ref='myInput'/>
          <input type='button' onClick={this.update.bind(this)} value='Update C2'/>
        </div>
      )
    }
    update () {
      this.props.onUpdate(this.refs.myInput.getDOMNode().value)
    }
})

class C2 extends React.Component {
    render () {
      return <div>{this.props.data}</div>
    }
})

ReactDOM.renderComponent(<Example/>, document.body)

5
Sorun değil. Aslında bu yazıyı yazdıktan sonra geri döndüm ve belgelerin bazılarını tekrar okudum ve onların düşünme ve en iyi uygulamaları ile satır içi gibi görünüyor. React gerçekten mükemmel belgelere sahiptir ve bir şeyin nereye gitmesi gerektiğini merak ettiğimde, genellikle belgelerin bir yerinde bulunur. Burada devletle ilgili bölüme göz atın, facebook.github.io/react/docs/…
captray

@captray ama C2bir getInitialStateveri varsa ve içinde renderkullanırsa ne olacak this.state.data?
Dmitry Polushkin

2
@DmitryPolushkin Sorunuzu doğru bir şekilde anlıyorsam, verileri Kök Bileşeninizden C2'ye sahne olarak aktarmak istiyorsunuz. C2'de, bu veriler başlangıç ​​durumu olarak ayarlanır (yani getInitialState: function () {return {someData: this.props.dataFromParentThatWillChange}} ve bileşenWillReceiveProps uygulamak ve bunu güncellemek için yeni props ile bu.setState'i çağırmak istersiniz. Başlangıçta yanıtladığımdan beri Flux kullanıyorum ve ona da bakmanızı şiddetle tavsiye ediyorum.Bu, bileşenlerinizi daha temiz hale getirir ve durum hakkında düşünme şeklinizi değiştirir.
captray

3
@DmitryPolushkin Bunu takibe göndermek istedim. facebook.github.io/react/tips/… Ne yaptığınızı bildiğiniz ve verilerin değişeceğini bildiğiniz sürece sorun yok, ancak çoğu durumda bir şeyler hareket ettirebilirsiniz. Bunu bir hiyerarşi olarak oluşturmak zorunda olmadığınızı da belirtmek önemlidir. C1 ve C2'yi DOM'daki farklı yerlere bağlayabilirsiniz ve her ikisi de bazı verilerdeki olayları değiştirmeyi dinleyebilir. Birçok insanın hiyerarşik bileşenler için ihtiyaç duymadıklarında zorlandığını görüyorum.
captray

5
Yukarıdaki kod 2 hata vardır - her ikisi de doğru bağlamda "bu" bağlama değil, yukarıdaki düzeltmeleri yaptım ve ayrıca bir kod açıklığı gösteri ihtiyacı olan herkes için: codepen.io/anon/pen/wJrRpZ?editors=0011
Alex H

34

React'i şimdi bir uygulama oluşturmak için kullandıktan sonra, yarım yıl önce sorduğum bu soruya bazı düşünceleri paylaşmak istiyorum.

Okumanızı tavsiye ederim

İlk gönderi, React uygulamanızı nasıl yapılandırmanız gerektiğini anlamak için son derece yararlıdır.

Flux , React uygulamanızı neden bu şekilde yapılandırmanız gerektiği sorusunu yanıtlar ( nasıl yapılandırılacağı yerine). Reaksiyon sistemin sadece% 50'sidir ve Flux ile tüm resmi görüp nasıl tutarlı bir sistem oluşturduklarını görebilirsiniz.

Soruya geri dön.

İlk çözümüme gelince , veriler hala tek yönlü olduğu için işleyicinin ters yöne gitmesine izin vermek tamamen sorun değildir .

Ancak, bir işleyicinin P'de bir setState'i tetiklemesine izin vermek, durumunuza bağlı olarak doğru veya yanlış olabilir.

Uygulama basit bir Markdown dönüştürücüyse, C1 ham girdi ve C2 HTML çıktısıysa, C1'in P'de bir setState'i tetiklemesine izin vermek sorun olmaz, ancak bazıları bunun önerilen yol olmadığını iddia edebilir.

Uygulamanın bir yapılacaklar listesi Ancak, C1 yeni todo üretmek için çalışmalar olma, C2 HTML yapılacaklar listesi, muhtemelen P ikiden düzey yukarı gitmek işleyicisi istiyorum - hiç dispatcherlet hangi storegüncelleştirme data store, bu da verileri P'ye gönderir ve görünümleri doldurur. Flux makalesine bakın. İşte bir örnek: Flux - TodoMVC

Genellikle yapılacaklar listesi örneğinde açıklanan yolu tercih ederim. Uygulamanızda ne kadar az eyalet varsa o kadar iyi olur.


7
Bunu hem React hem de Flux sunumlarında sık sık tartışıyorum. Vurgulamaya çalıştığım nokta, yukarıda tanımladığınız şeydir ve bu, Görünüm Durumu ile Uygulama Durumunun ayrılmasıdır. İşlerin yalnızca Görünüm Durumu olmaktan Uygulama Durumu haline geçebileceği durumlar vardır, özellikle de kullanıcı arayüzünün durumunu kaydettiğiniz durumlarda (önceden ayarlanmış değerler gibi). Bir yıl sonra kendi düşüncelerinle geri dönmen harika bir şey. +1
captray

@captray Yani redux'un her koşulda tepki vermekten daha güçlü olduğunu söyleyebilir miyiz? Öğrenme eğrilerine rağmen ... (Java'dan geliyor)
Bruce Sun

Ne anlatmak istediğinden emin değilim. İki farklı şeyi çok iyi idare ediyorlar ve endişelerin doğru bir şekilde ayrılıyorlar.
captray

1
Redux kullanan bir projemiz var ve aylar içinde her şey için eylemler kullanılıyor gibi görünüyor. Bu büyük bir spagetti kodu karışımı ve anlaşılması imkansız, tam bir felaket gibi. Devlet yönetimi iyi olabilir, ancak büyük olasılıkla yanlış anlaşılabilir. Flux / redux'un sadece küresel olarak erişilmesi gereken devlet bölümleri için kullanılması gerektiğini düşünmek güvenli midir?
wayofthefuture

1
@wayofthefuture Kodunuzu görmeden, iyi ole spagetti jQuery gibi çok fazla spagetti React gördüğümü söyleyebilirim. Sunabileceğim en iyi tavsiye SRP'yi denemek ve takip etmektir. Bileşenlerinizi mümkün olduğunca basit hale getirin; dilerseniz render bileşenleri. Ayrıca bir <DataProvider /> bileşeni gibi soyutlamalar için de baskı yapıyorum. Bir şey iyi gidiyor. Veri sağlamak. Bu genellikle 'kök' bileşen olur ve verileri sahne olarak (ve klonlama) destek (tanımlanmış sözleşme) olarak kaldırarak verileri aktarır. Sonuçta, önce Sunucu üzerinde düşünmeye çalışın. Daha iyi veri yapılarıyla JS'nizi daha temiz hale getirecektir.
captray

6

Beş yıl sonra React Hooks'un piyasaya sürülmesiyle, useContext hook'u kullanmanın çok daha zarif bir yolu var.

Genel bir kapsamda bağlam tanımlar, üst bileşendeki değişkenleri, nesneleri ve işlevleri dışa aktarır ve ardından alt öğeleri uygulamada sağlanan bağlamda sarar ve alt bileşenlerde ihtiyacınız olan her şeyi içe aktarırsınız. Aşağıda bir kavram kanıtıdır.

import React, { useState, useContext } from "react";
import ReactDOM from "react-dom";
import styles from "./styles.css";

// Create context container in a global scope so it can be visible by every component
const ContextContainer = React.createContext(null);

const initialAppState = {
  selected: "Nothing"
};

function App() {
  // The app has a state variable and update handler
  const [appState, updateAppState] = useState(initialAppState);

  return (
    <div>
      <h1>Passing state between components</h1>

      {/* 
          This is a context provider. We wrap in it any children that might want to access
          App's variables.
          In 'value' you can pass as many objects, functions as you want. 
           We wanna share appState and its handler with child components,           
       */}
      <ContextContainer.Provider value={{ appState, updateAppState }}>
        {/* Here we load some child components */}
        <Book title="GoT" price="10" />
        <DebugNotice />
      </ContextContainer.Provider>
    </div>
  );
}

// Child component Book
function Book(props) {
  // Inside the child component you can import whatever the context provider allows.
  // Earlier we passed value={{ appState, updateAppState }}
  // In this child we need the appState and the update handler
  const { appState, updateAppState } = useContext(ContextContainer);

  function handleCommentChange(e) {
    //Here on button click we call updateAppState as we would normally do in the App
    // It adds/updates comment property with input value to the appState
    updateAppState({ ...appState, comment: e.target.value });
  }

  return (
    <div className="book">
      <h2>{props.title}</h2>
      <p>${props.price}</p>
      <input
        type="text"
        //Controlled Component. Value is reverse vound the value of the variable in state
        value={appState.comment}
        onChange={handleCommentChange}
      />
      <br />
      <button
        type="button"
        // Here on button click we call updateAppState as we would normally do in the app
        onClick={() => updateAppState({ ...appState, selected: props.title })}
      >
        Select This Book
      </button>
    </div>
  );
}

// Just another child component
function DebugNotice() {
  // Inside the child component you can import whatever the context provider allows.
  // Earlier we passed value={{ appState, updateAppState }}
  // but in this child we only need the appState to display its value
  const { appState } = useContext(ContextContainer);

  /* Here we pretty print the current state of the appState  */
  return (
    <div className="state">
      <h2>appState</h2>
      <pre>{JSON.stringify(appState, null, 2)}</pre>
    </div>
  );
}

const rootElement = document.body;
ReactDOM.render(<App />, rootElement);

Bu örneği Kod Sandbox düzenleyicisinde çalıştırabilirsiniz.

Bağlamla geçiş durumunu düzenleme


5

Birinci çözüm ile , ana bileşen olarak durum aynen olduğu doğru bir . Bununla birlikte, daha karmaşık problemler için, bazı devlet yönetimi kütüphaneleri hakkında düşünmelisiniz , redux tepki ile kullanılan en popüler olanıdır.


Kabul. Yanıtım çoğu "saf tepki" de bir şeyler yazarken geri yazıldı. Akı yayılmasından önce.
captray

2

Yazdığım anda basit bir deyimsel React çözümü ile cevap bulunmamasına şaşırdım. İşte burada (boyut ve karmaşıklığı diğerleriyle karşılaştırın):

class P extends React.Component {
    state = { foo : "" };

    render(){
        const { foo } = this.state;

        return (
            <div>
                <C1 value={ foo } onChange={ x => this.setState({ foo : x })} />
                <C2 value={ foo } />
            </div>
        )
    }
}

const C1 = ({ value, onChange }) => (
    <input type="text"
           value={ value }
           onChange={ e => onChange( e.target.value ) } />
);

const C2 = ({ value }) => (
    <div>Reacting on value change: { value }</div>
);

Bir alt öğeden üst öğenin durumunu ayarlıyorum. Bu, React'in tasarım prensibine ihanet ediyor gibi görünüyor: tek yönlü veri akışı.

Herhangi bir kontrollüinput (React'taki formlarla çalışmanın deyimsel yolu), ana durumu onChangegeri çağrısında günceller ve yine de hiçbir şeye ihanet etmez.

Örneğin C1 bileşenine dikkatlice bakın. Nasıl şekilde herhangi önemli bir fark görüyor musunuz C1dahili ve inputdurum değişiklikleri bileşeni sap? Yapmamalısınız, çünkü hiç yok. Durumu kaldırmak ve değeri / onChange çiftlerini geçmek ham Reaksiyon için deyimseldir. Bazı cevapların önerdiği gibi refs kullanımı değil.


1
Hangi tepkiyi kullanıyorsunuz? Deneysel sınıf özelliği sorunları alıyorum ve foo tanımlanmadı.
Isaac Pak

Bu bir tepki versiyonuyla ilgili değildi. Bileşenin kodu yanlış. Düzeltildi, şimdi deneyin.
gaperton

Açıkçası, devlet üyesini çıkarmak zorundasınız this.state, dönüş render olarak eksikti ve birden fazla bileşen div veya başka bir şeyle sarılmalıdır. Orijinal cevabı yazarken bunu nasıl özlediğimi bilmiyorum. Düzenleme hatası olmalı.
gaperton

1
Bu çözümü seviyorum. Birisi onunla uğraşmak istiyorsa, işte sizin için bir sanal alan .
Isaac Pak

2

Kullanan bir örnekle daha yeni yanıt React.useState

Durumu ana bileşende tutmak önerilen yoldur. Ebeveynin iki çocuk bileşeninde yönettiği için ona erişmesi gerekir. Redux tarafından yönetilen gibi küresel devlet taşıyarak, bir değil neden aynı aynı nedenle önerilen genel değişken yerel kötüdür yazılım mühendisliğinde genel olarak.

Durum üst bileşendeyken, üst öğe alt öğeye valueve onChangeişleyiciye destek verirse çocuk bunu değiştirebilir (bazen değer bağlantısı veya durum bağlantısı deseni olarak adlandırılır ). Kancalarla nasıl yapacağınız aşağıda açıklanmıştır:


function Parent() {
    var [state, setState] = React.useState('initial input value');
    return <>
        <Child1 value={state} onChange={(v) => setState(v)} />
        <Child2 value={state}>
    </>
}

function Child1(props) {
    return <input
        value={props.value}
        onChange={e => props.onChange(e.target.value)}
    />
}

function Child2(props) {
    return <p>Content of the state {props.value}</p>
}

Ana bileşenin tamamı alt öğedeki giriş değişikliğinde yeniden oluşturulur; bu, üst bileşenin yeniden oluşturulması küçük / hızlıysa sorun olmayabilir. Ana bileşenin yeniden oluşturma performansı hala genel durumda bir sorun olabilir (örneğin büyük formlar). Bu sizin durumunuzda çözülmüş bir sorundur (aşağıya bakınız).

Hookstate gibi 3. taraf kitaplığını kullanarak durum bağlantı düzenini ve üst öğeyi yeniden oluşturmayı uygulamak daha kolaydır - sizinkiReact.useState de dahil olmak üzere çeşitli kullanım durumlarını kapsayacak şekilde süper şarj edilir. (Feragatname: Projenin yazarıyım).

Hookstate ile böyle görünecekti. Child1girişi değiştirecek, Child2tepki verecektir. Parentdevleti elinde tutacaktır ancak devlet değişikliğinde yeniden yaratmayacak, sadece Child1ve Child2yapacak.

import { useStateLink } from '@hookstate/core';

function Parent() {
    var state = useStateLink('initial input value');
    return <>
        <Child1 state={state} />
        <Child2 state={state}>
    </>
}

function Child1(props) {
    // to avoid parent re-render use local state,
    // could use `props.state` instead of `state` below instead
    var state = useStateLink(props.state)
    return <input
        value={state.get()}
        onChange={e => state.set(e.target.value)}
    />
}

function Child2(props) {
    // to avoid parent re-render use local state,
    // could use `props.state` instead of `state` below instead
    var state = useStateLink(props.state)
    return <p>Content of the state {state.get()}</p>
}

Not: orada çoktur fazla örnek burada içe geçmiş veriler, devlet doğrulama, küresel devlet dahil olmak üzere benzer ve daha karmaşık senaryolar kapsayan setStatevb kanca, Otelde ayrıca çevrimiçi tam örnek uygulama Hookstate kullanır ve teknik yukarıda açıkladı.


1

Redux ve ReactRedux kütüphanesini öğrenmelisiniz. Durumlarınızı ve sahne eşyalarınızı tek bir mağazada yapılandıracak ve daha sonra bileşenlerinizden erişebilirsiniz.


1

React> = 16.3 ile, çocuğun DOM'sinden üst öğesinden erişim elde etmek için ref ve forwardRef kullanabilirsiniz. Artık eski refs yollarını kullanmayın.
İşte davanızı kullanan örnek:

import React, { Component } from 'react';

export default class P extends React.Component {
   constructor (props) {
      super(props)
      this.state = {data: 'test' }
      this.onUpdate = this.onUpdate.bind(this)
      this.ref = React.createRef();
   }

   onUpdate(data) {
      this.setState({data : this.ref.current.value}) 
   }

   render () {
      return (
        <div>
           <C1 ref={this.ref} onUpdate={this.onUpdate}/>
           <C2 data={this.state.data}/>
        </div>
      )
   }
}

const C1 = React.forwardRef((props, ref) => (
    <div>
        <input type='text' ref={ref} onChange={props.onUpdate} />
    </div>
));

class C2 extends React.Component {
    render () {
       return <div>C2 reacts : {this.props.data}</div>
    }
}

Bkz refs ve ForwardRef sayılı referanslarda ve forwardRef ilgili detaylı bilgi için.


0
  1. Yapılacak doğru şey , üst bileşende durumun olması, ref'den kaçınmak ve neyin olmamasıdır
  2. Bir sorun, bir alana yazarken tüm çocukları sürekli güncellemekten kaçınmaktır
  3. Bu nedenle, her çocuk bir Bileşen (PureComponent değil) olmalı ve uygulamalıdır. shouldComponentUpdate(nextProps, nextState)
  4. Bu şekilde, bir form alanına yazarken yalnızca bu alan güncellenir

Aşağıdaki kod , BabelJS 6'nın ES.Next öğesinden ve sınıf özelliklerinden @boundek açıklamalar kullanır (ek açıklama, bu değeri bağlamaya benzer üye işlevlerinde ayarlar): babel-plugin-transform-decorators-legacy

/*
© 2017-present Harald Rudell <harald.rudell@gmail.com> (http://www.haraldrudell.com)
All rights reserved.
*/
import React, {Component} from 'react'
import {bound} from 'class-bind'

const m = 'Form'

export default class Parent extends Component {
  state = {one: 'One', two: 'Two'}

  @bound submit(e) {
    e.preventDefault()
    const values = {...this.state}
    console.log(`${m}.submit:`, values)
  }

  @bound fieldUpdate({name, value}) {
    this.setState({[name]: value})
  }

  render() {
    console.log(`${m}.render`)
    const {state, fieldUpdate, submit} = this
    const p = {fieldUpdate}
    return (
      <form onSubmit={submit}> {/* loop removed for clarity */}
        <Child name='one' value={state.one} {...p} />
        <Child name='two' value={state.two} {...p} />
        <input type="submit" />
      </form>
    )
  }
}

class Child extends Component {
  value = this.props.value

  @bound update(e) {
    const {value} = e.target
    const {name, fieldUpdate} = this.props
    fieldUpdate({name, value})
  }

  shouldComponentUpdate(nextProps) {
    const {value} = nextProps
    const doRender = value !== this.value
    if (doRender) this.value = value
    return doRender
  }

  render() {
    console.log(`Child${this.props.name}.render`)
    const {value} = this.props
    const p = {value}
    return <input {...p} onChange={this.update} />
  }
}

0

Verilerin ebeveynten çocuğa geçmesi ve tam tersi kavramı açıklanmaktadır.

import React, { Component } from "react";
import ReactDOM from "react-dom";

// taken refrence from https://gist.github.com/sebkouba/a5ac75153ef8d8827b98

//example to show how to send value between parent and child

//  props is the data which is passed to the child component from the parent component

class Parent extends Component {
  constructor(props) {
    super(props);

    this.state = {
      fieldVal: ""
    };
  }

  onUpdateParent = val => {
    this.setState({
      fieldVal: val
    });
  };

  render() {
    return (
      // To achieve the child-parent communication, we can send a function
      // as a Prop to the child component. This function should do whatever
      // it needs to in the component e.g change the state of some property.
      //we are passing the function onUpdateParent to the child
      <div>
        <h2>Parent</h2>
        Value in Parent Component State: {this.state.fieldVal}
        <br />
        <Child onUpdate={this.onUpdateParent} />
        <br />
        <OtherChild passedVal={this.state.fieldVal} />
      </div>
    );
  }
}

class Child extends Component {
  constructor(props) {
    super(props);

    this.state = {
      fieldValChild: ""
    };
  }

  updateValues = e => {
    console.log(e.target.value);
    this.props.onUpdate(e.target.value);
    // onUpdateParent would be passed here and would result
    // into onUpdateParent(e.target.value) as it will replace this.props.onUpdate
    //with itself.
    this.setState({ fieldValChild: e.target.value });
  };

  render() {
    return (
      <div>
        <h4>Child</h4>
        <input
          type="text"
          placeholder="type here"
          onChange={this.updateValues}
          value={this.state.fieldVal}
        />
      </div>
    );
  }
}

class OtherChild extends Component {
  render() {
    return (
      <div>
        <h4>OtherChild</h4>
        Value in OtherChild Props: {this.props.passedVal}
        <h5>
          the child can directly get the passed value from parent by this.props{" "}
        </h5>
      </div>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById("root"));


1
Cevabınızdaki açıklamayı eklemek için önceki cevap sahibini yorum olarak bilgilendirmenizi öneririm. Ardından adınızı bir nezaket için referans alarak.
Thomas Easo

@ThomasEaso Onu burada bulamıyorum, kontrol ettim. Başka öneri var mı
akshay

simgesinin solundaki "düzenle" düğmesini tıklayın ve yanıtını değiştirin ve gönderin. bir moderatöre gidecek ve sizin değerli yorumlarınıza ihtiyaç duyacaklardır.
Thomas Easo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.