React实践debug:JSX输出的限制(存疑)

今天在练习React构建组件的时候遇到一个问题。

由于文档中反复提倡将组件尽可能按功能单位分解复用。在练习用React做一个todolist时候,我把todolist分解成两部分:

class Todolist = class Writedown + class Todo;

其中 class Writedown返回 一个input和一个button 以接收和确定 用户输入的文本。

 class Todo 是一个li,展示todo事项并带有删除事项的span。之所以抽取li标签作为Todo组件是考虑到以后扩展功能,如对单个事项添加修改文本、置顶、标记已完成等等。

但是在写完class Todo的时候发现检测工具却报错,说Todolist的constructor构造器出现Syntax Error。

Are you kdding me?

最后发现是 class Todo 引发的问题,这次的报错完全不真实,并误导了我。。反复排查,我怀疑是render返回的JSX受到HTML类型约束.

在vue中,我们的自定义组件也一样,当DOM模板解析时,也受到HTML的限制,在table、ul等元素中限制了其包裹的html标签:

<table><tr is="my-row"></tr></table>

我们只能在tr 中用借用is特性绑定自定义组件my-row。

我这次在子组件中返回li,React居然报错说我有个syntax error,并指出是unexpected token,真是一脸懵逼。。。。

React实践debug:JSX输出的限制(存疑)

----------------------------------------------------------------------------------------

但是在官网中,有个例子是function组件返回li,这让我很疑惑。https://facebook.github.io/react/docs/lists-and-keys.html#extracting-components-with-keys.

这问题先记下,这两天弄清楚。

 ----------------------9月4号晚  更新--------------------------------

然后发现。。返回li确实没有问题。。。

这实在是最难接受的情况了。浏览器不再报错,但是代码结构是和原来差不多的。

 1   class Write extends React.Component {
 2     constructor(props){
 3       super(props);
 4       this.handle=this.handle.bind(this);
 5     }
 6     handle(){
 7       const text=document.getElementById('todoIn').value;
 8       this.props.onWriteDown(text);
 9     }
10     render(){
11      return (
12      <div>
13     <input type="text" id="todoIn" />
14      <button onClick={this.handle}>confirm</button>
15      </div>
16      );
17     }
18   }
19   //Todo组件输出li,接收delete方法
20   class Todo extends React.Component {
21     constructor(props){
22       super(props);
23       this.handle=this.handle.bind(this);
24     }
25     handle(){
26     }
27     render(){
28      return (
29      <li onClick={this.props.onDel}>{this.props.mes}</li>
30      );
31     }
32   }
33 
34   //Todolist组件,用todolist数组操作、存储事项,交互后赋值给state,也就是说state接收的是副本。
35  class Todolist extends React.Component {
36      constructor (props) {
37       super(props);
38       this.n=0;
39       this.state={list:[]};
40       this.todolist=[];
41       this.handle=this.handle.bind(this);
42       this.handle_del=this.handle_del.bind(this);
43     }
44     handle (m) {
45       this.todolist.push({thing:m,vid:this.n++});
46       this.setState({list:this.todolist});
47     }
48     handle_del (id) {
49        let d =0;
50        this.todolist.forEach((v,i)=>{
51          if(v.vid==id){
52            d=i;
53          }
54       });
55       this.todolist.splice(d,1);
56        this.setState({list:this.todolist});
57     }
58     render(){
59     var that = this;
60       var todo=[];
61       this.state.list.forEach(function(v,i,a){
62       let id = v.vid.toString();
63       console.log(v.thing)
64        let temp=<Todo  key={id} onDel={() => that.handle_del(id)}  mes={v.thing} ></Todo>;
65         todo.push(temp);
66       });
67       return(
68       <div>
69         <Write onWriteDown={this.handle} /> 
70         <ul>
71         {todo}
72         </ul>
73        </div>
74       );
75     }
76   }
77 
78    ReactDOM.render(
79       <Todolist />,
80      document.getElementById('example')
81    );

    不过现在可以确定的是,JSX的可以输出li、tr等。