на моем ubuntu 14.04, apache 2.4, php 5.5.9 install, я попробовал с sample.php on / var / www / html (root по умолчанию), и он работал нормально. Таким образом, проблема была в моей конфигурации виртуальных серверов. Решение заключалось в том, чтобы включить в директорию def, содержащую .php, следующую строку:
php_admin_flag engine on
initGrid
вовсе не обязательно должен быть частью компонента, он не привязан к состоянию, за исключением того, что он пытается его обновить.
Он может быть вспомогательной функцией и использоваться при необходимости:
function initGrid(rows) {
...
return {
rows,
grid,
fullColumns,
};
}
class App extends React.Component {
state = initGrid(6);
...
}
Создайте дублирующую функцию initGrid
, предназначенную для использования только в конструкторе (присваивая непосредственно this.state
вместо использования setState
) , Помимо дублирования кода и явного нарушения DRY, это также создает дополнительный метод «одноразового использования» , который приводит к предупреждению «Не изменять состояние напрямую, используйте setState ()», что довольно раздражает. .
Использовать анонимную самопризывающую функцию, которая присваивает непосредственно this.state.grid
и this.state.fullColumns
в конструкторе:
constructor(props) {
// ...
[this.state.grid, this.state.fullColumns] = (function(rows) {
let grid = [];
let fullColumns = [];
let cols = rows + 1;
for (let c = 0; c < cols; c++) {
fullColumns.push(false);
let column = [];
for (let r = 0; r < rows; r++) {
column.push(null);
}
grid.push(column);
}
return [grid, fullColumns];
})(this.state.rows);
}
componentWillMount
теперь можно удалить. Это также избавляет от предупреждения «Не изменять состояние напрямую, используйте setState ()» и не приводит к бессмысленному созданию другого метода для одноразового использования. Но он все еще излишне дублирует код из this.initGrid
.
Просто жестко закодируйте начальную сетку и массивы fullColumns в состоянии:
constructor(props) {
super(props);
this.state = {
rows: 6,
grid: [
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
[null, null, null, null, null, null],
],
fullColumns: [false, false, false, false, false, false, false]
}
}
componentWillMount
теперь можно удалить. Это приносит в жертву настраиваемость и чувствует себя довольно непрофессионально. Однако, это не без его собственных преимуществ; это приводит к меньшему количеству логики, более эффективно, а также помогает в визуализации / документировании кода.
Измените функцию initGrid
, чтобы отличать вызов ее от конструктора от вызова из другого места:
initGrid(rows) {
// Create grid data structure to keep track of which grid cells
// contain checkers of which color:
// 'grid' = array of COLUMN arrays!
let cols = rows + 1;
let grid = [];
let fullColumns = [];
for (let c = 0; c < cols; c++) {
fullColumns.push(false);
let column = [];
for (let r = 0; r < rows; r++) {
column.push(null);
}
grid.push(column);
}
// If 'this.state.grid' is already initialised (i.e. non-empty),
// the call is NOT from inside the constructor:
if (this.state.grid.length !== 0) {
this.setState({
rows,
grid,
fullColumns,
});
} else {
// If the grid is empty, this call came from inside the constructor,
// so we disable the "Do not mutate state directly, Use setState()" warning:
// eslint-disable-next-line react/no-direct-mutation-state
this.state = {
...this.state,
grid,
fullColumns,
}
}
}
Это не излишне дублирует код и сохраняет настраиваемость. Он по-прежнему имеет предупреждение «Не изменять состояние напрямую, используйте setState ()», но он глушит комментарий // eslint-...
. Теперь мы можем вызвать this.initGrid(this.state.rows)
в конструкторе, а не в componentWillMount
.
Это похоже на самое профессиональное решение для меня.
Вы можете использовать его в конструкторе, просто замените
this.setState({
rows,
grid,
fullColumns
});
на
this.state = {
...this.state
rows,
grid,
fullColumns
}
<час> . Вы также можете переместить initGrid
в метод componentDidMount
путем рендеринга. null
когда состояние компонента не полностью инициализировано или не обеспечивает значимых значений по умолчанию.
render() {
if(this.state.grid) {
return ...
}
else {
return null;
}
}