1
votes

N'utilisez pas de constructeur

Dans mon code, je n'ai pas utilisé constructor () . J'ai toujours vu des gens utiliser le constructeur dans des composants de classe, mais même si je ne l'utilise pas dans ce code, cela fonctionne parfaitement. Dans mon code, mettre l'état en dehors du constructeur, est-ce une bonne idée ou serait-il préférable d'utiliser le constructeur avec l'état défini à l'intérieur? Cela peut-il donner une sorte d'erreur à l'avenir ou aggraver les performances de mon système? Qu'est-ce qu'il est préférable de faire dans ce cas?

import React, { Component, Fragment } from 'react'
import  {Redirect} from 'react-router-dom'
import { connect } from 'react-redux'

import ActionCreator from '../redux/actionCreators'

import Button from '../elements/Button'

const statsgenre = {
'Ação': 'Action',
'Comédia': 'Comedy',
'Drama': 'Drama'
} 


const statsuser = {
'Assistido' : 'Watched',
'Assistindo': 'Watching',
'Assistir': 'Watch' 
}


class ScreensEditSeries extends Component{

state = {
    id: '',
    name: '',
    status: '',
    genre: '',
    notes: ''
}

componentDidMount = () => {    
    const serie  = {...this.props.match.params}
    this.props.load(serie)
    this.props.reset()
}

static getDerivedStateFromProps(newProps, prevState){
    let serie = {}
    if (prevState.name === '' || prevState.name === undefined){  
        if (newProps.series.serie.name !== prevState.name){
            serie.name = newProps.series.serie.name
        }

        if (newProps.series.serie.genre !== prevState.genre){
            serie.genre = newProps.series.serie.genre
        }

        if (newProps.series.serie.status !== prevState.status){
            serie.status = newProps.series.serie.status
        }
        if (newProps.series.serie.notes !== prevState.notes){
            serie.notes = newProps.series.serie.notes
        }
        return serie
    }           
}

saveSeries = () => {
    const {name, status, genre, notes} = this.state
    const id = this.props.match.params.id
    const newSerie = {
        id,
        name,
        status,
        genre,
        notes
    }
    this.props.save(newSerie)
}

handleChange = field => event => {
    this.setState({[field] : event.target.value})
}

render(){
    return (
        <Fragment>
            <div className="container">         
                <div>  
                    {this.props.series.saved  && <Redirect to={`/series/${this.props.match.params.genre}`}/>}
                    <h1 className='text-white'>Edit Série</h1>
                    {!this.props.series.isLoadding && <Button>
                        Name: <input type="text" value={this.state.name} onChange={this.handleChange('name')} className="form-control" /><br />
                        Status: {<span>&nbsp;</span>} 
                        <select value={this.state.status} onChange={this.handleChange('status')}>
                            {Object.keys(statsuser)
                                .map( key => <option key={key}>{statsuser[key]}</option>)}
                        </select><br/><br/>
                        Genre: {<span>&nbsp;</span>} 
                        <select value={this.state.genre} onChange={this.handleChange('genre')}>
                            {Object.keys(statsgenre)
                                .map(key => <option key={key}>{statsgenre[key]}</option>)}
                        </select><br/><br/>
                        Notes: <textarea type='text' value={this.state.notes} onChange={this.handleChange('notes')} className="form-control"></textarea><br />
                        <button className="button button2" type="button" onClick={this.saveSeries}>Save</button>
                    </Button>}
                    {this.props.series.isLoadding && <p className='text-info'>Loading...</p>}
                </div>
            </div>
        </Fragment>
    )
}
}

const mapStateToProps = state => {
return {
    series: state.series
}
}

const mapDispatchToProps = dispatch => {
return {
    load : serie => dispatch(ActionCreator.getSerieRequest(serie)),
    save: newSerie => dispatch(ActionCreator.updateSerieRequest(newSerie)),
    reset : () => dispatch(ActionCreator.seriesReset()),
}

}

export default connect(mapStateToProps, mapDispatchToProps)(ScreensEditSeries) 


0 commentaires

3 Réponses :


2
votes

Il n'y a aucun problème à utiliser des composants de classe sans constructeur. Habituellement, vous en avez besoin au cas où vous auriez à faire du travail pour préparer l'état, traiter certains accessoires ou configurer certaines variables d'instance dès que le composant est instancié.

C'est bon :)

Ici, à la place, il y a un article très intéressant de Dan Abramov expliquant pourquoi, si vous avez besoin d'utiliser le constructeur, il est nécessaire d'appeler super (props) :

https://overreacted.io/why-do-we- write-super-props /

Pas super lié à la question, mais posant des questions sur le constructeur, j'ai pensé que cela pourrait vous être utile.


1 commentaires

@ schu34, Matthew et 0xc14m1z Herbst, merci les gars, vous avez beaucoup aidé .. Quand j'ai utilisé bind, il était vraiment nécessaire d'utiliser le constructeur, mais maintenant, avec les fonctions fléchées, je n'ai plus besoin d'utiliser le constructeur, car j'initialise le state dans componentDidMount ou getDerivedStateFromProps.



2
votes

Il n'y a pas de différence. La raison pour laquelle vous voyez la plupart des gens le faire à l'intérieur du constructeur est que faire state = {} directement sur la classe est une nouvelle syntaxe qui n'a pas encore été largement adoptée (elle nécessite souvent encore une transformation Babel ou similaire). Voir proposal-class-fields pour plus d'informations à ce sujet . Une chose à noter est que si vous avez besoin d'accéder à des accessoires pour initialiser l'état, vous devez le faire dans le constructeur .


0 commentaires

2
votes

En général, vous ne devriez utiliser un constructeur que si vous avez besoin de logique lorsque la classe est créée pour la première fois, ou si votre configuration dépend des accessoires passés. Puisque tout dans votre état initial est codé en dur, ne pas utiliser de constructeur est bien dans ce cas cas.


0 commentaires