| 12 | const isAddMode = pathname => pathname.startsWith('/msg/add') |
| 13 | |
| 14 | export default class MsgForm extends Component { |
| 15 | static contextTypes = { |
| 16 | router: PropTypes.object.isRequired |
| 17 | } |
| 18 | |
| 19 | constructor (props, context) { |
| 20 | // 既然用到了 context,显然需要 super 一下咯 |
| 21 | // 实际上最完善的形式的确就是如下写法 |
| 22 | super(props, context) |
| 23 | |
| 24 | // 初始 state 必须定义,否则会报错 |
| 25 | // 就像在 Vue 中需要在 data 中定义默认值 |
| 26 | this.state = getInitState() |
| 27 | |
| 28 | this.handleChange = handleChange.bind(this) // mixin |
| 29 | } |
| 30 | |
| 31 | componentDidMount() { |
| 32 | this.updateState() |
| 33 | } |
| 34 | |
| 35 | /** |
| 36 | * 由于本组件为共用组件,但 React 本身不提供类似 Vue 的 canReuse 属性 |
| 37 | * 在 /msg/add <==> /msg/modify/:msgId 之间的跳转,组件保持挂载状态 |
| 38 | * 故需要利用本函数更新 state。不在乎性能者可利用我们的 hack:Redirect 组件 |
| 39 | */ |
| 40 | componentWillReceiveProps(nextProps) { |
| 41 | this.updateState(nextProps) // 传入 nextProps |
| 42 | } |
| 43 | |
| 44 | /* 不传入 props 则默认使用当前 props */ |
| 45 | updateState ({ location, params: { msgId }, userData: { username }, msg: { msgs } } = this.props) { |
| 46 | // 情况1:处于 /msg/add,直接就是还原初始状态 |
| 47 | if (isAddMode(location.pathname)) { |
| 48 | return this.setState(getInitState()) |
| 49 | } |
| 50 | |
| 51 | // 情况2:处于 /msg/modify/:msgId,且 state 中 msgs 不为空 |
| 52 | if (msgs.length) { |
| 53 | let nextState = msgs.filter(({ id }) => id === msgId)[0] |
| 54 | if (!nextState || nextState.author !== username) { |
| 55 | return this.handleIllegal() |
| 56 | } |
| 57 | return this.setState(nextState) |
| 58 | } |
| 59 | |
| 60 | // 情况3:强制刷新 /msg/detail/:msgId 后,跳转到 /msg/modify/:msgId |
| 61 | // 此时 state 中 msgs 为空,需要立即从后端 API 获取 |
| 62 | msgService.fetch({ msgId }).then(msg => { |
| 63 | let { id, title, content, author } = msg |
| 64 | if (!msg || author !== username) { |
| 65 | return this.handleIllegal() |
| 66 | } |
| 67 | this.setState({ id, title, content }) |
| 68 | }) |
| 69 | } |
| 70 | |
| 71 | handleIllegal () { |
nothing calls this directly
no outgoing calls
no test coverage detected