【发布时间】:2016-03-28 21:49:18
【问题描述】:
我正在慢慢学习 React,同时也在学习用 Redux 来实现它。但我似乎遇到了障碍。这就是我到目前为止所拥有的。
/index.jsx
import './main.css'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/App.jsx'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import ShoppingList from './reducers/reducer'
let store = createStore(ShoppingList)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app')
)
/actions/items.js
import uuid from 'node-uuid'
export const CREATE_ITEM = 'CREATE_ITEM'
export function createItem(item) {
return {
type: CREATE_ITEM,
item: {
id: uuid.v4(),
item,
checked: false
}
}
}
/reducers/reducer.js
import * as types from '../actions/items'
import uuid from 'node-uuid'
const initialState = []
const items = (state = initialState, action) => {
switch (action.type) {
case types.CREATE_ITEM:
return {
id: uuid.v4(),
...item
}
default:
return state;
}
}
export default items
/reducers/index.js
更新:
import { combineReducers } from 'redux'
import items from './reducer'
const ShoppingList = combineReducers({
items
})
export default ShoppingList
/components/Item.jsx
import React from 'react';
import uuid from 'node-uuid'
export default class Item extends React.Component {
constructor(props) {
super(props);
this.state = {
isEditing: false
}
}
render() {
if(this.state.isEditing) {
return this.renderEdit();
}
return this.renderItem();
}
renderEdit = () => {
return (
<input type="text"
ref={(event) =>
(event ? event.selectionStart = this.props.text.length : null)
}
autoFocus={true}
defaultValue={this.props.text}
onBlur={this.finishEdit}
onKeyPress={this.checkEnter}
/>
)
};
renderDelete = () => {
return <button onClick={this.props.onDelete}>x</button>;
};
renderItem = () => {
const onDelete = this.props.onDelete;
return (
<div onClick={this.edit}>
<span>{this.props.text}</span>
{onDelete ? this.renderDelete() : null }
</div>
);
};
edit = () => {
this.setState({
isEditing: true
});
};
checkEnter = (e) => {
if(e.key === 'Enter') {
this.finishEdit(e);
}
};
finishEdit = (e) => {
const value = e.target.value;
if(this.props.onEdit) {
this.props.onEdit(value);
this.setState({
isEditing: false
});
}
};
}
/components/Items.jsx
import React from 'react';
import Item from './Item.jsx';
export default ({items, onEdit, onDelete}) => {
return (
<ul>{items.map(item =>
<li key={item.id}>
<Item
text={item.text}
onEdit={onEdit.bind(null, item.id)}
onDelete={onDelete.bind(null, item.id)}
/>
</li>
)}</ul>
);
}
// UPDATE: http://redux.js.org/docs/basics/UsageWithReact.html
// Is this necessary?
const mapStateToProps = (state) => {
return {
state
}
}
Items = connect(
mapStateToPros
)(Items) // `SyntaxError app/components/Items.jsx: "Items" is read-only`
//////////////////////////////////////
// Also tried it this way.
//////////////////////////////////////
Items = connect()(Items)
export default Items // same error as above.
也试过了
export default connect(
state => ({
items: store.items
})
)(Items) // `Uncaught TypeError: Cannot read property 'items' of undefined`
更新:
经过多次尝试,Gitter 中的@hedgerh 指出它应该是 state.items。所以解决方案是
export default connect(
state => ({
items: state.items
})
)(Items)
也归功于@azium。
/components/App.jsx
export default class App extends React.Component {
render() {
return (
<div>
<button onClick={this.addItem}>+</button>
<Items />
</div>
);
}
}
为了正确实施它,我在这里遗漏了什么?现在它打破了在Items.jsx 中说Uncaught TypeError: Cannot read property 'map' of undefined。我想这是有道理的,因为它似乎没有正确连接。这是应用程序的第一部分,第二部分将允许用户创建许多列表,这些列表包含许多项目。我可能不得不从Item.jsx 中提取方法,因为List.jsx 会做几乎相同的事情。谢谢
【问题讨论】:
-
您的示例中似乎缺少
App.jsx..items是如何传递给<Items />的? -
有些东西需要
connected 到你的商店。所以要么你忘了展示那部分,要么你需要在某个地方添加它。 -
我想这就是我不确定的。我有一个 App.jsx,等一下,我会更新我的问题。 @azium
-
您是否使用
<provider>将商店传给它的孩子?店铺是怎么传承下来的?你在 App.jsx 中使用connect吗? -
@James111 我正在使用
<Provider>查看我的 index.js。我也经过那里的商店。如果我通过使用Provider并在那里传递商店来正确理解它,那么我的子组件将可以使用该商店。正确的?现在我如何连接应用程序有点模糊。
标签: reactjs redux react-redux