reactjs I get Error无法读取未定义(阅读“name”)呈现UI的属性

j8ag8udp  于 2023-03-17  发布在  React
关注(0)|答案(1)|浏览(96)

无法读取未定义(阅读“name”)的属性类型错误:无法读取未定义的属性(阅读“name”)
index.js

import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {legacy_createStore as createStore} from 'redux'
import { Provider } from 'react-redux';

const store = createStore((state = [], action) => {
  if (action.type === 'ADD') return [...state, action.name];
  return state;
});

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

reportWebVitals();

App.js

import React, { createRef } from 'react';
import { connect } from 'react-redux';

const Item = ({ name, price }) => (<li>{name},${price}</li>)
       
const App = (props) => {
  let nameRef = createRef();
  let priceRef = createRef();

  const add = () => {
    props.add(
      props.items.length +1,
      nameRef.current.value,
      priceRef.current.value,
    )
  }

  return (
    <div>
      <ul>
        {props.items.map(i => (
          <Item key={i.id} name={i.name} price={i.price} />
        ))}
      </ul>

      <input type="text" ref={nameRef} />
      <input type="text" ref={priceRef} />
      <button onClick={add}>Add</button>
    </div>
  )
}

const stateToProps = state => {
  return {
    items: state
  }
}

const dispatchToProps = dispatch => {
  return {
    add: (id, name, price) => {
      dispatch ({
        type: 'ADD',
        item: { id, name, price }
      })
    }
  }
}

const ReduxApp = connect(stateToProps, dispatchToProps)(App);
export default ReduxApp

Error

无法读取未定义(阅读'name')类型的属性错误:无法读取未定义的属性(阅读“name”)

qni6mghb

qni6mghb1#

问题数量
我不知道为什么代码没有在i.id上抛出错误,但问题是每次调度ADD操作时,都将undefined推入state数组。

add: (id, name, price) => {
  dispatch ({
    type: 'ADD',
    item: { id, name, price }
  })
}

action对象有两个属性:typeitem,但是当在reducer函数中处理分派的动作时,将action.name(即undefined)追加到数组中。
x一个一个一个一个x一个一个二个x
选择state并将其作为props.items注入App组件,Map后,每个数组元素值为undefined,代码尝试访问属性并抛出错误。

<ul>
  {props.items.map(i => (
    <Item
      key={i.id}
      name={i.name} // <-- oops, i is undefined!
      price={i.price}
    />
  ))}
</ul>

溶液

正确访问ADD action有效负载。您使用的是非常过时的redux模式,因此我将重写部分代码,使其与更传统的redux保持一致,这将使您更容易升级或使用现代redux。
index.js

import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {legacy_createStore as createStore} from 'redux'
import { Provider } from 'react-redux';

const rootReducer = (state = [], action) => {
  switch(action.type) {
    case 'ADD':
      return [...state, action.payload];

    default:
      return state;
  }
};

const store = createStore(rootReducer);

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

App.js

import React, { createRef } from 'react';
import { connect } from 'react-redux';

const Item = ({ name, price }) => <li>{name}, ${price}</li>;

const addItem = (payload) => ({
  type: 'ADD',
  payload
});
       
const App = ({ addItem, items }) => {
  const nameRef = createRef();
  const priceRef = createRef();

  const add = () => {
    addItem({
      id: items.length + 1,
      name: nameRef.current.value,
      price: priceRef.current.value,
    });
  };

  return (
    <div>
      <ul>
        {items.map(item => (
          <Item key={item.id} name={item.name} price={item.price} />
        ))}
      </ul>
      <input type="text" ref={nameRef} />
      <input type="text" ref={priceRef} />
      <button type="button" onClick={add}>Add</button>
    </div>
  )
}

const mapStateToProps = state => ({
  items: state
});

const mapDispatchToProps =  {
  addItem
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

更现代的版本将使用useDispatchuseSelector钩子来代替过时的connect高阶组件。
App.js

import React, { createRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';

const Item = ({ name, price }) => <li>{name}, ${price}</li>;

const addItem = (payload) => ({
  type: 'ADD',
  payload
});
       
const App = () => {
  const dispatch = useDispatch();
  const items = useSelector(state => state);

  const nameRef = createRef();
  const priceRef = createRef();

  const add = () => {
    dispatch(addItem({
      id: items.length + 1,
      name: nameRef.current.value,
      price: priceRef.current.value,
    }));
  };

  return (
    <div>
      <ul>
        {items.map(item => (
          <Item key={item.id} name={item.name} price={item.price} />
        ))}
      </ul>
      <input type="text" ref={nameRef} />
      <input type="text" ref={priceRef} />
      <button type="button" onClick={add}>Add</button>
    </div>
  )
}

export default App;

相关问题