Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.9k views
in Technique[技术] by (71.8m points)

react项目, 在页面修改saga models文件的拿到的state, 为什么会直接更新了

models.js

export default {
    namespace: 'myModel',
    state: {
        data: {
          list: [
              { i: 1, disabled: false},
              { i: 2, disabled: false},
              { i: 3, disabled: false},
          ],
          keys: '',
    },
},
effects: {
    *fetch({ payload }, { call, put }) {
      const response = yield call(getData, payload);
      yield put({
        type: 'update',
        payload: response,
      });
    },
},
  reducers: {
    saveState(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
  }
};

A页面

// 方法
const handle = () => {
    const { myModel: { data } } = this.props;
    data.list.forEach(item => item.disabled = true };
    
    // 为什么我没执行下面的代码 这个在model 里的 data 也会更新了
    // dispatch({
        // type: 'myModel/saveState',
        // payload: {
            // data
        // }
    // })
}

B页面

 render() {
    const { myModel: { data } } = this.props;
    // A页面执行了handle方法后 为什么这里的data也会更新了
    console.log(data);
 }



分割线
或者说我上面操作是错的? 应该先把数据放到A页面的state, 不能直接修改props

A页面

constuctor() {
    super();
    this.state = {
        myData: props.myModel.data
    }
}
// 方法
const handle = () => {
    const { myData } = this.state;
    myData.list.forEach(item => item.disabled = true };
    
    dispatch({
        type: 'myModel/saveState',
        payload: {
            data: myData
        }
    })
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

谢邀...首先撇开 react 和 redux 的概念,看最基础的 js 代码:

var obj = {};
var obj1 = obj;

obj1.name = 'test';
console.log(obj);

上面的代码执行后会发现,明明没有修改 obj 但为啥 obj 也会改变呢?答案是在 js 中对象、数组这种类型是引用类型,你单纯的赋值对象其实给的是同一份引用。

因此在该函数中所修改的对象都是同一份的:

const handle = () => {
    const { myModel: { data } } = this.props;
    
    // 在此处已经被修改了 
    // 这是具有副作用的操作
    data.list.forEach(item => item.disabled = true };
}

回到 React 的概念,react 提倡纯函数,因此你在修改时可以新建对象来代替直接修改:

const handle = () => {
    const { myModel: { data } } = this.props;
    
    // 完全新建
    const newData = {
        ...data,
        list: data.list.map(item => ({ ...item, disabled: true }))
    }
}

这样就不会有依赖之外的情况出现了。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...