在ReactJs中更改对象状态值会给我警告(不要直接更改状态。请使用setState()

时间:2019-08-16 15:50:39

标签: javascript reactjs react-native

如何更改对象的状态?我是这样做的,但我认为这是不对的,因为在编译时会给出setState警告。 我想了解如何更改其值为对象的状态。


class Animation extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            step    : step,
            ledge   :{zoom:1, display:"flex"},
            map     :{zoom:0, x:0, y:0, rotate:0},
        };
    }
    StepForward = () => {
        step = step + 1;
        //STEP 1
        if(step === 1){
            this.setState({ 
                ...this.state.ledge.zoom = this.state.ledge.zoom - 1, 
                ...this.state.ledge.display = "none"
             });   
        }
    }
    StepBack = () => {
        step = step - 1;
        if(step < 0 ){
            this.setState({step:step})
            step = -1
        }
        //STEP 0
        if(step === 0){
            this.setState({ 
                ...this.state.ledge.zoom = this.state.ledge.zoom + 1, 
                ...this.state.ledge.display = "flex",});
        }
    }
    render() {
        return (
            <div id="content_animation">
               <div id="step back" class="command" onClick={this.StepBack}>
                   <img class="arrow" src="img/arrow_b.svg" alt="back"/>
               </div>
               <div id="animation">
                   <AnimationStep 
                    step = {this.state.step}
                    ledge={this.state.ledge}
                    map={this.state.map}/>
               </div>
               <div id="step forward" class="command" onClick={this.StepForward}>
                  <img class="arrow" src="img/arrow_f.svg" alt="forward"/>        
               </div>
           </div>
        )
    }
}
export default Animation

当我编译它时,会出现以下错误,但如果在代码行“错误”的上方插入注释,则它可以正常工作并正确编译...

Compiled with warnings.

Do not mutate state directly. Use setState()  react/no-direct-mutation-state
Do not mutate state directly. Use setState()  react/no-direct-mutation-state
Do not mutate state directly. Use setState()  react/no-direct-mutation-state
Do not mutate state directly. Use setState()  react/no-direct-mutation-state

Search for the keywords to learn more about each warning.
To ignore, add //eslint-disable-next-line to the line before.

4 个答案:

答案 0 :(得分:3)

正如错误明确指出的那样,您正在直接更改状态,这将在整个过程中导致错误。您可以设置状态而无需进行如下更改:

<div class="tool is-activatable"
      v-if="config.isVisibleToUser"
      @click="dispatch"
      :class="[config.cssClass, {'is-active': active, 'is-highlighted': highlight, 'is-button': !context.reordering}]"
      :command-id="config.command"
      :context-menu-name="contextMenu.name"
      :context-menu-details="contextMenu.contextMenuDetails"
      :data-id="config.id"
      :disabled="disabled"
      :data-placement="inMenu ? 'right-top' : config.tooltipPosition || 'bottom'"
      :data-original-title="(config.tooltipKey || config.tooltip || config.toolName) | i18next"
      :data-expanded-content="(config.expandedTooltipKey || config.expandedTooltip) | i18next" data-html="true"
      :data-expand-delay="inMenu ? 0 : config.expandDelay > -1 ? config.expandDelay : 2000"
      :data-trigger="config.tooltipTrigger"
      :tooltip-dynamic-snippet-id="dynamicSnippetId">

  <img v-if="!hasIcon && config.img" :src="config.img" />
  <ToolIcon v-if="hasIcon" :icon="config.icon" :iconUri="config.iconUri" :initials="config.iconInitials"
            :awaitingData="false" :updateAvailable="config.isNewerVersionAvailable"/>
  <span v-if="spinnerToggle && command-id=='updateAllExternalReferences'">Spin</span>

  <span class="tool-label" :class="{'hide-in-toolbar': !shouldShowLabel}">
    {{ (config.toolDisplayName || config.toolName) | i18next }}
  </span>
  <ShortcutKeys v-if="inMenu" :shortcut="shortcut" />
  <div v-if="context.reordering" class="drag-handle"></div>
</div>

有用的链接:

正在更改状态-https://daveceddia.com/why-not-modify-react-state-directly/

功能this.setState(state => ({ ...state, ledge: { ...state.ledge, zoom: state.ledge.zoom - 1, display: 'none' } })); -https://www.freecodecamp.org/news/functional-setstate-is-the-future-of-react-374f30401b6b/

对象传播-https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals

答案 1 :(得分:-1)

问题出在您的setState通话中,以及如何设置这些值:

this.setState({
  ledge: {
    zoom: this.state.ledge.zoom - 1,
    display: 'none'
  }
});

答案 2 :(得分:-1)

  

请不要直接更改this.state,因为之后调用setState()可能会替换您所做的更改。将此this.state视为不可变。

您也许想检查可变和不可变之间的区别。

在这种情况下,您应该使用扩展运算符:

        this.setState(prevState => ({
        ledge: {                   // object that we want to update
            ...prevState.ledge,    // keep all other key-value pairs
            zoom: this.state.ledge.zoom -1       // update the value of specific key
        }
    }))

答案 3 :(得分:-1)

使用this.setState时,不必在其中的作业中明确说出this.state。我无法按照您或其他答案的方式设置内部类。我通常会采取另一步骤来成功设置状态。

this.setState({ 
    ...this.state.ledge.zoom = this.state.ledge.zoom + 1, 
    ...this.state.ledge.display = "flex",});

成为:

var tempLedge = this.state.ledge;
tempLedge.zoom = this.state.ledge.zoom + 1;
tempLedge.display = "flex";

this.setState({ledge = tempLedge});

相关但不是欺骗:
What is the correct way of setting state variables in Reactjs and what is the difference between these approaches?

另外,请查看此链接以获取更多信息:State and Lifecycle