tôi có lẽ sẽ khuyên bạn nên đi về vấn đề này khác nhau: cửa hàng chỉ trạng thái cần thiết để tính toán thời gian trôi qua trong cửa hàng, và để cho các thành phần thiết riêng khoảng của họ cho tuy nhiên họ thường muốn cập nhật màn hình.
Điều này giúp hành động gửi đến mức tối thiểu - chỉ các hành động để bắt đầu và dừng (và đặt lại) hẹn giờ được gửi đi. Hãy nhớ rằng, bạn đang trả về một đối tượng trạng thái mới mỗi lần bạn gửi một hành động và mỗi thành phần ed connect
ed sau đó hiển thị lại (mặc dù chúng sử dụng tối ưu hóa để tránh quá nhiều lần hiển thị lại trong các thành phần được bao bọc).Hơn nữa, nhiều công văn hành động có thể làm cho nó khó khăn để gỡ lỗi thay đổi trạng thái ứng dụng, vì bạn phải xử lý tất cả các số TICK
cùng với các hành động khác.
Dưới đây là một ví dụ:
// Action Creators
function startTimer(baseTime = 0) {
return {
type: "START_TIMER",
baseTime: baseTime,
now: new Date().getTime()
};
}
function stopTimer() {
return {
type: "STOP_TIMER",
now: new Date().getTime()
};
}
function resetTimer() {
return {
type: "RESET_TIMER",
now: new Date().getTime()
}
}
// Reducer/Store
const initialState = {
startedAt: undefined,
stoppedAt: undefined,
baseTime: undefined
};
function reducer(state = initialState, action) {
switch (action.type) {
case "RESET_TIMER":
return {
...state,
baseTime: 0,
startedAt: state.startedAt ? action.now : undefined,
stoppedAt: state.stoppedAt ? action.now : undefined
};
case "START_TIMER":
return {
...state,
baseTime: action.baseTime,
startedAt: action.now,
stoppedAt: undefined
};
case "STOP_TIMER":
return {
...state,
stoppedAt: action.now
}
default:
return state;
}
}
const store = createStore(reducer);
Thông báo những người sáng tạo hành động và giao dịch giảm chỉ với các giá trị nguyên thủy, và không sử dụng bất kỳ loại khoảng hoặc một loại TICK
hành động. Bây giờ là một thành phần có thể dễ dàng đăng ký vào dữ liệu này và cập nhật thường xuyên như nó muốn:
// Helper function that takes store state
// and returns the current elapsed time
function getElapsedTime(baseTime, startedAt, stoppedAt = new Date().getTime()) {
if (!startedAt) {
return 0;
} else {
return stoppedAt - startedAt + baseTime;
}
}
class Timer extends React.Component {
componentDidMount() {
this.interval = setInterval(this.forceUpdate.bind(this), this.props.updateInterval || 33);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
const { baseTime, startedAt, stoppedAt } = this.props;
const elapsed = getElapsedTime(baseTime, startedAt, stoppedAt);
return (
<div>
<div>Time: {elapsed}</div>
<div>
<button onClick={() => this.props.startTimer(elapsed)}>Start</button>
<button onClick={() => this.props.stopTimer()}>Stop</button>
<button onClick={() => this.props.resetTimer()}>Reset</button>
</div>
</div>
);
}
}
function mapStateToProps(state) {
const { baseTime, startedAt, stoppedAt } = state;
return { baseTime, startedAt, stoppedAt };
}
Timer = ReactRedux.connect(mapStateToProps, { startTimer, stopTimer, resetTimer })(Timer);
Bạn thậm chí có thể hiển thị nhiều giờ trên cùng một dữ liệu với một tần số cập nhật khác nhau:
class Application extends React.Component {
render() {
return (
<div>
<Timer updateInterval={33} />
<Timer updateInterval={1000} />
</div>
);
}
}
Bạn có thể thấy một working JSBin với thực hiện điều này ở đây: https://jsbin.com/dupeji/12/edit?js,output
Tôi xin lỗi vì nhận xét muộn của tôi, nhưng cảm ơn rất nhiều! Đọc qua tất cả điều này thực sự đã giúp tôi hiểu rõ hơn về cách tôi nên cấu trúc/thiết kế tất cả những điều này. Tôi có hai câu hỏi nếu bạn không phiền. Đầu tiên là tại sao mã trên không hoạt động nếu tôi sử dụng 'null' thay vì' undefined'? Thứ hai, tôi là một chút không chắc chắn về dòng 'clearInterval (this.interval);'. 'This.interval' được định nghĩa ở đâu? Hay bạn muốn làm điều này 'this.interval = setInterval()' ở trên nó? Cảm ơn một lần nữa nó có nghĩa là rất nhiều mà bạn sẽ đi ra khỏi con đường của bạn để làm điều này! – saadq
@meh_programmer Tôi đã sử dụng 'undefined' để đối số mặc định trong các tác vụ' getElapsedTime' (chuyển undefined làm cho nó sử dụng mặc định, nhưng đó không phải là trường hợp khi truyền null). Bạn nói đúng về khoảng thời gian - Tôi sẽ sửa lỗi đó! :) –
nhanh Lưu ý: Có vẻ bạn có chức năng thuần túy phi trong giảm: new Date(): "Nó rất quan trọng là giảm vẫn tinh khiết Những điều bạn không bao giờ nên làm bên trong một giảm ...." Từ tài liệu https: //github.com/reactjs/redux/blob/master/docs/basics/Reducers.md Thực tiễn tốt nhất tôi nghĩ là có tất cả các tạp chất trong ActionCreators https://github.com/reactjs/redux/issues/1088 –