我正在尝试将React组件的构造函数传递给另一个应该具有setState事件处理程序的组件。我应该如何将“ this”绑定到处理程序?
这是App组件,具有数据作为状态,例如:
const App = function(props, context) {
this.props = props;
this.context = context;
};
App.prototype = Object.create(React.Component.prototype);
App.prototype.state = {
datum: [
{
isTicked: true,
otherData: "otherData_1"
/* Other data inside object */
},
{
isTicked: false,
otherData: "otherData_2"
/* Other data inside object */
},
{
isTicked: true,
otherData: "otherData_3"
/* Other data inside object */
}
]
};
这是Table组件,它基于props.row
上的回调构造组件,如下所示:
index.js:
// index.js
const Table = require("./table.js");
table.js:
// table.js
module.exports = (props, context) => (
<table>
<thead>
<tr>{Object.keys(props.row).map(k => <th>{k}</th>)}</tr>
</thead>
<tbody>
{props.datum.map((obj, index) => (
<tr>
{Object.keys(props.row).map(k => (
<td>
{props.row[k] instanceof Function
? props.row[k](obj, index)
: props.row[k]}
</td>
))}
</tr>
))}
</tbody>
</table>
);
我像这样通过props.row
:
App.prototype.tableRow = {
T: (data, index) => (
<input
type="checkbox"
checked={data.isTicked}
onChange={e => {
this.setState(prevState => {
prevState.datum[index].isTicked = !prevState.datum[index]
.isTicked;
return {
datum: prevState.datum
};
});
}}
/>
),
otherData: data => data.otherData
};
App.prototype.render = function() {
return <Table datum={this.state.datum} row={this.tableRow} />;
};
这里的问题是,当我传递一个构造函式元素的回调函数props.row
并应在this.setState
事件上调用onClick
时,我无法绑定this
作为通常的事件处理函数。
这是我的CodeSandBox示例,它显示了这种情况:
https://codesandbox.io/s/jjlvvwjvpv
您可以看到,如果单击它表示undefined is not an object (evaluating 'undefined.setState')
的复选框,则表明计算结果为未定义。
我应该如何处理this
?
答案 0 :(得分:1)
也许您可以通过将App.prototype.tableRow
对象修改为以下内容来解决此问题:
App.prototype.tableRow = {
T: function(data, index) { /* <--- Use regular function here, rather than arrow function */
return <input
type="checkbox"
checked={data.isTicked}
onChange={e => {
this.setState(prevState => {
prevState.datum[index].isTicked = !prevState.datum[index].isTicked;
return {
datum: prevState.datum
};
});
}}
/>
},
otherData: data => data.otherData
};
然后,像这样更新渲染功能:
App.prototype.render = function() {
/* Clone the tableRow object from prototype, and bind T function to this instance */
const tableRow = { ...this.tableRow };
tableRow.T = tableRow.T.bind(this);
return <Table datum={this.state.datum} row={tableRow} />;
};
这里是a working demo on codesandbox-希望对您有所帮助!