英文:
My autocomplete package doesn't update the state
问题
以下是您要翻译的代码部分:
// 使用 Algolia Places 自动完成地址输入。
// 然而,当我检查组件的状态时,我发现点击按钮后,即使字段内的文本发生更改,状态也没有更新。
// 我不明白,为什么不起作用,因为我已经正确设置了 handleChange 函数。
export function handleChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
}
export function addAlgolia() {
    var places = require('places.js');
    var placesAutocomplete = places({
    appId: "APPID",
    apiKey: "APIKEY",
    container: document.querySelector('#address-input')
    });
}
示例输入代码:
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import Dashboard from '../Dashboard'
import Axios from 'axios'
import * as Cookies from 'js-cookie'
import ErrorContainer from '../../components/ErrorContainer'
import { addAlgolia, handleChange } from 'utils'
export class OrganismSettings extends Component {
    constructor(props) {
        super(props);
        this.state = { loading: true, organism: [], name: "", description: "", address: "", picture: null }
        this.getOrganism = this.getOrganism.bind(this);
        this.handleChange = handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleChangePicture = this.handleChangePicture.bind(this);
    }
    componentDidMount() {
        this.getOrganism();
        addAlgolia()
    }
    // ... 省略了其他方法和渲染部分 ...
}
export default withRouter(OrganismSettings)
英文:
I use Algolia Places to autocomplete my address input.
However, when I check the state of my component, I can see that clicking on the button, even if the text changes inside the field, doesn't update the state.
I don't get it, why it doesn't work, since I setup my handleChange function correctly.
export function handleChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  }
export function addAlgolia() {
    var places = require('places.js');
    var placesAutocomplete = places({
    appId: "APPID",
    apiKey: "APIKEY",
    container: document.querySelector('#address-input')
    });
}
Example code for input :
import React, { Component } from 'react'
import {withRouter} from 'react-router-dom'
import Dashboard from '../Dashboard'
import Axios from 'axios'
import * as Cookies from 'js-cookie'
import ErrorContainer from '../../components/ErrorContainer'
import { addAlgolia, handleChange } from 'utils'
export class OrganismSettings extends Component {
    constructor(props) {
        super(props);
        this.state = {loading: true, organism: [], name: "", description: "", address: "", picture: null}
        this.getOrganism = this.getOrganism.bind(this);
        this.handleChange = handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleChangePicture = this.handleChangePicture.bind(this);
    }
    componentDidMount() {
        this.getOrganism();
        addAlgolia()
    }
    getOrganism() {
        Axios.get('http://localhost:8000/api/organism/settings', {headers: {Accept: 'application/json', Authorization: 'Bearer ' + Cookies.get('token')}})
        .then((success) => {
            var organism = success.data.data.organism;
            this.setState({organism: success.data.data.organism, loading: false})
            this.setState({name: organism.name, description: organism.description, address: organism.address})
        }, (error) => {
            this.props.history.push('/organisme/creation')
        })
    }
      handleChangePicture(event) {
        this.setState({picture: event.target.files[0]})
    }
    handleSubmit(e) {
        e.preventDefault();
        var formData = new FormData();
        formData.append('name', this.state.name);
        formData.append('description', this.state.description);
        formData.append('address', this.state.address);
        formData.append('picture', this.state.picture);
        formData.append('_method', 'PATCH');
        var token = Cookies.get('token');
        Axios.post('http://localhost:8000/api/organism/settings', formData, {
            headers: {
                "Accept": 'application/json',
                "Authorization": `Bearer ${token}`,
            }
        }).then(
            (success) => {
                this.setState({loading: false});
                //this.props.history.push('/organisme')
            }, (error) => {
                this.setState({errors : error.response.data.data})
                if(error.response.data.redirect != "") {
                    this.props.history.push(error.response.data.redirect)
                }
            }
        )
    }
    render() {
        return (
            <Dashboard loading={this.state.loading}>
                <section className="section has-text-centered">
                    <div className="column is-offset-1 is-10">
                    <h1 className="title is-size-1 register-title">Paramètres de {this.state.name}</h1>
                        <section className="section organism-register">
                            <form encType="multipart/form-data" className="user-form fullbox-form" method="POST" onSubmit={this.handleSubmit}>
                                <div className="has-text-left input-fixer">
                                <label className="is-size-4">Nom de l'organisme : </label><input type="text" name="name" placeholder="Nom de l'organisme" value={this.state.name} onChange={this.handleChange}/>
                                <label className="is-size-4">Description de l'organisme : </label><textarea name="description" placeholder="Description de l'organisme" value={this.state.description} onChange={this.handleChange}/>
                                <label className="is-size-4">Adresse de l'organisme : </label><input id="address-input" type="text" name="address" value={this.state.address} onChange={this.handleChange}></input>
                                <label className="is-size-4">Ajouter le logo de votre organisme : </label>
                                <input type="file" name="picture" onChange={this.handleChangePicture} />
                                </div>
                                <ErrorContainer errors={this.state.errors} />
                                <button className="button is-primary has-text-left">Soumettre les changements</button>
                            </form>
                        </section>
                    </div>
                </section>
            </Dashboard>
        )
    }
}
export default withRouter(OrganismSettings)
答案1
得分: 0
Algolia Places会仅更新输入的一个值,因此您需要自行添加与状态的同步。最佳方案是使用库提供的事件:
https://community.algolia.com/places/documentation.html#events
在您的代码中:
export function addAlgolia() {
    var places = require('places.js');
    var placesAutocomplete = places({
       appId: "APPID",
       apiKey: "APIKEY",
       container: document.querySelector('#address-input')
    });
    placesAutocomplete.on('change', e => {
         const value = e.suggestion;
         // 在这里,您需要调用类似 this.setState(...) 的内容,将“value”传递给您的主要组件
    });
}
英文:
Algolia Places updates just a value of the input, so You have to add synchronization with state on Your own.
The best fit would be to use events provided by the library:
https://community.algolia.com/places/documentation.html#events
in Your code:
export function addAlgolia() {
    var places = require('places.js');
    var placesAutocomplete = places({
       appId: "APPID",
       apiKey: "APIKEY",
       container: document.querySelector('#address-input')
    });
    placesAutocomplete.on('change', e => {
         const value = e.suggestion;
         // here You have to call something like this.setState(...) with "value" for Your main component
    });
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论