Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 渲染组件不';t对其道具更新作出回应_Javascript_Reactjs_React Native_React Props_React State - Fatal编程技术网

Javascript 渲染组件不';t对其道具更新作出回应

Javascript 渲染组件不';t对其道具更新作出回应,javascript,reactjs,react-native,react-props,react-state,Javascript,Reactjs,React Native,React Props,React State,我正在创建与Trello“相似”的React应用程序。在我们有项目,项目有板,板有列,列有任务等等。默认情况下,只有包含带有板名称的条的项目才可见,其余的项目应隐藏。如果你点击一个标题栏,整个内容都应该是可见的。此外,当您再次单击此栏时,它应再次隐藏。我希望这是清楚的 问题是,我在一个组件(ProjectView)中呈现了带有板名的条形图,其中包含许多子组件(Board),这些组件最终可以呈现每个板的内容(BoardView)。在ProjectView中,我有一个映射(visibilityMap

我正在创建与Trello“相似”的React应用程序。在我们有项目,项目有板,板有列,列有任务等等。默认情况下,只有包含带有板名称的条的项目才可见,其余的项目应隐藏。如果你点击一个标题栏,整个内容都应该是可见的。此外,当您再次单击此栏时,它应再次隐藏。我希望这是清楚的

问题是,我在一个组件(ProjectView)中呈现了带有板名的条形图,其中包含许多子组件(Board),这些组件最终可以呈现每个板的内容(BoardView)。在ProjectView中,我有一个映射(visibilityMap),它将isHidden布尔值指定给电路板的名称。此映射中的相应值将传递给每个Board组件的道具,Board组件将其传递给BoardView,在BoardView中,它用于为包含内容的div定义隐藏的atribute值。另外,在ProjectView中,我有一个函数,在点击一个合适的电路板名称后,可以更改地图中的布尔值。在日志中,我可以看到,单击board name后,visibilityMap中的特定值会发生变化,但不会改变特定board内容的可见性

我花了很多时间在这上面,尝试了很多奇怪的事情,但我不知道出了什么问题。下面我附上了所描述组件的代码和两个屏幕截图——点击board name前后

项目视图-几乎所有内容都在renderBoard上

从“React”导入React;
从“react bootstrap”导入{Button};
从“@material ui/core/TextField”导入TextField;
从“@material ui/core/Dialog”导入对话框;
从“@material ui/core/DialogActions”导入DialogActions;
从“@material ui/core/DialogContent”导入DialogContent;
从“@material ui/core/DialogTitle”导入DialogTitle;
从“./控制器/板”导入板;
从“反应颜色”导入{PhotoshopPicker};
需要(“../styles/Project.css”);
需要(“../../styles/Board.css”);
类ProjectView扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
渲染:假,
莫达尔肖:错,
莫达拉德肖:错,
modalBoard:“,
董事会名称:“,
背景:“橙色”,
新名称:“,
新背景:“,
showAddBackground:false,
showChangeBackground:false,
pickedBackground:“橙色”,
验证:正确,
visibilityMap:新地图()
};
this.handleChange=this.handleChange.bind(this);
}
渲染板=()=>{
if(this.props.boards.length==0){
返回(Brak board'w!)
}
if(this.state.visibilityMap.size==0){
this.props.boards.map(board=>this.state.visibilityMap.set(board.name,true))
}
返回此.props.boards.map(board=>
此.渲染板(板)
);
};
RenderModel=(板)=>{
这是我的国家({
莫达尔肖:没错,
modalBoard:board,
newName:board.name,
新背景:board.background,
})
};
handleChangeColor=(颜色)=>{
这是我的国家({
pickedBackground:颜色
})
};
handleCancelColor=()=>{
这是我的国家({
showAddBackground:false,
showChangeBackground:false,
})
};
handleAcceptAddColor=()=>{
const newColor=this.state.pickedBackground.hex;
这是我的国家({
背景:newColor,
showAddBackground:false
})
};
handleAcceptChangeColor=()=>{
const newColor=this.state.pickedBackground.hex;
这是我的国家({
新背景:新颜色,
showChangeBackground:错误
})
};
渲染板=(板)=>{
常量handleClose=()=>{
这是我的国家({
新名称:“,
新背景:“,
modalShow:错误
})
};
常量开关可见性=()=>{
const oldValue=this.state.visibilityMap.get(board.name)
this.state.visibilityMap.set(board.name,!oldValue)
}
常量handleEdit=()=>{
this.props.handleEdit(this.state.modalBoard.name,this.state.newName,this.state.newBackground);
handleClose();
这是我的国家({
模板:“
});
};
返回(
{board.name}
X
这个.renderModal(board)}
variant=“警告”
>
O
Edytuj boarda{this.state.modalBoard.name}
这是我的国家({
showChangeBackground:是的,
pickedBackground:this.state.newBackground
})}
>
科洛尔:
Kolor boarda{board.name}
阿努鲁伊
import React from 'react';
import {Button} from "react-bootstrap";
import TextField from '@material-ui/core/TextField';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import Board from "../controllers/Board";
import {PhotoshopPicker} from 'react-color';

require("../../styles/Project.css");
require("../../styles/Board.css");

class ProjectView extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            render: false,
            modalShow: false,
            modalAddShow: false,
            modalBoard: "",
            boardName: "",
            boardBackground: "orange",
            newName: "",
            newBackground: "",
            showAddBackground: false,
            showChangeBackground: false,
            pickedBackground: "orange",
            validate: true,
            visibilityMap: new Map()
        };
        this.handleChange = this.handleChange.bind(this);
    }

    renderBoards = () => {
        if (this.props.boards.length === 0) {
            return (<div className="no-content">Brak board'ów!</div>)
        }

        if (this.state.visibilityMap.size === 0) {
            this.props.boards.map(board => this.state.visibilityMap.set(board.name, true))
        }

        return this.props.boards.map(board =>
            this.renderBoard(board)
        );
    };

    renderModal = (board) => {
        this.setState({
            modalShow: true,
            modalBoard: board,
            newName: board.name,
            newBackground: board.background,
        })
    };

    handleChangeColor = (color) => {
        this.setState({
            pickedBackground: color
        })
    };

    handleCancelColor = () => {
        this.setState({
            showAddBackground: false,
            showChangeBackground: false,
        })
    };

    handleAcceptAddColor = () => {
        const newColor = this.state.pickedBackground.hex;
        this.setState({
            boardBackground: newColor,
            showAddBackground: false
        })
    };

    handleAcceptChangeColor = () => {
        const newColor = this.state.pickedBackground.hex;
        this.setState({
            newBackground: newColor,
            showChangeBackground: false
        })
    };

    renderBoard = (board) => {
        const handleClose = () => {
            this.setState({
                newName: "",
                newBackground: "",
                modalShow: false
            })
        };

        const switchVisibility = () => {
            const oldValue = this.state.visibilityMap.get(board.name)
            this.state.visibilityMap.set(board.name, !oldValue)
        }

        const handleEdit = () => {
            this.props.handleEdit(this.state.modalBoard.name, this.state.newName, this.state.newBackground);
            handleClose();
            this.setState({
                modalBoard: ""
            });
        };

        return (
            <div className="board" style={{backgroundColor: board.background}}>
                <div className="bookmark board-head" onClick={switchVisibility}>
                    {board.name}
                    <Button
                        className="action-button delete"
                        id={board.name}
                        onClick={this.handleDelete}
                        variant="danger"
                    >
                        X
                    </Button>
                    <Button
                        className="action-button edit"
                        id={board.name}
                        onClick={() => this.renderModal(board)}
                        variant="warning"
                    >
                        O
                    </Button>
                    <Dialog open={this.state.modalShow} aria-labelledby="form-dialog-title">
                        <DialogTitle id="form-dialog-title">Edytuj boarda {this.state.modalBoard.name}</DialogTitle>
                        <DialogContent>
                            <TextField
                                autoFocus
                                margin="dense"
                                name="newName"
                                label="Nazwa boarda"
                                type="text"
                                onChange={this.handleChange}
                                value={this.state.newName}
                                fullWidth
                            />
                            <div style={{display: "flex", flexFlow: "nowrap row"}}>
                                <Button
                                    variant="light"
                                    onClick={() => this.setState({
                                        showChangeBackground: true,
                                        pickedBackground: this.state.newBackground
                                    })}
                                >
                                    Kolor:
                                </Button>
                                <div className="color-box"
                                     style={{background: this.state.newBackground}}>
                                </div>
                                <Dialog open={this.state.showChangeBackground} aria-labelledby="form-dialog-title">
                                    <DialogTitle id="form-dialog-title">Kolor boarda {board.name}</DialogTitle>
                                    <DialogContent>
                                        <PhotoshopPicker
                                            header="Wybierz kolor"
                                            onAccept={this.handleAcceptChangeColor}
                                            onCancel={this.handleCancelColor}
                                            color={this.state.pickedBackground}
                                            onChangeComplete={this.handleChangeColor}/>
                                    </DialogContent>
                                </Dialog>
                            </div>
                        </DialogContent>
                        <DialogActions>
                            <Button onClick={handleClose} color="primary">
                                Anuluj
                            </Button>
                            <Button
                                onClick={handleEdit}
                                disabled={this.state.newName === "" || !this.state.validate}
                                color="primary">
                                Zapisz
                            </Button>
                        </DialogActions>
                    </Dialog>
                </div>
                <Board isHidden={this.state.visibilityMap.get(board.name)} boardReference={board.ref}
                       name={board.name}/>
            </div>
        )
    };

    renderAddModal = () => {
        this.setState({
            modalAddShow: true,
        })
    };

    renderAddBoard = () => {
        const handleClose = () => {
            this.setState({
                modalAddShow: false,
                newName: ""
            })
        };

        const handleAdd = () => {
            this.props.handleSubmit(this.state.boardName, this.state.boardBackground);
            this.setState({boardName: "", boardBackground: "orange"});
            handleClose();
            this.setState({
                modalBoard: ""
            });
        };

        return (
            <div>
                <Button
                    className="add-button new-board"
                    onClick={this.renderAddModal}
                    variant="success"
                >
                    +
                </Button>
                <Dialog open={this.state.modalAddShow} aria-labelledby="form-dialog-title">
                    <DialogTitle id="form-dialog-title">Dodaj board'a</DialogTitle>
                    <DialogContent>
                        <TextField
                            autoFocus
                            margin="dense"
                            name="boardName"
                            label="Nazwa"
                            type="text"
                            onChange={this.handleChange}
                            value={this.state.boardName}
                            fullWidth
                        >
                        </TextField>
                        <div style={{display: "flex", flexFlow: "nowrap row"}}>
                            <Button
                                margin="dense"
                                fullWidth
                                variant="light"
                                onClick={() => this.setState({
                                    showAddBackground: true
                                })}
                            >
                                Kolor:
                            </Button>
                            <div className="color-box"
                                 style={{background: this.state.boardBackground}}>
                            </div>
                        </div>
                        <Dialog open={this.state.showAddBackground} aria-labelledby="form-dialog-title">
                            <DialogTitle id="form-dialog-title">Kolor nowego boarda</DialogTitle>
                            <DialogContent>
                                <PhotoshopPicker
                                    header="Wybierz kolor"
                                    onAccept={this.handleAcceptAddColor}
                                    onCancel={this.handleCancelColor}
                                    color={this.state.pickedBackground}
                                    onChangeComplete={this.handleChangeColor}/>
                            </DialogContent>
                        </Dialog>
                    </DialogContent>
                    <DialogActions>
                        <Button onClick={handleClose} color="primary">
                            Anuluj
                        </Button>
                        <Button onClick={handleAdd}
                                disabled={this.state.boardName === "" || !this.state.validate}
                                color="primary">
                            Dodaj
                        </Button>
                    </DialogActions>
                </Dialog>
            </div>
        );
    };

    handleDelete = e => {
        e.preventDefault();
        this.props.handleDelete(e.target.id);
    };

    handleChange = e => {
        e.preventDefault();
        const isValid = this.validator(e.target)
        this.setState({
            [e.target.name]: e.target.value,
            validate: isValid
        });
    };

    validator = input => {
        if (input.name === "newName" && this.state.modalBoard.name === input.value)
            return true
        const filter = this.props.boards.find(board =>
            board.name === input.value
        )
        return typeof (filter) === "undefined"
    }

    componentDidMount() {
        setTimeout(function () {
            this.setState({render: true})
        }.bind(this), 1000)
    }

    render() {
        let renderContainer = false;
        if (this.state.render) {
            renderContainer =
                <div className="project-body">
                    {this.renderBoards()}
                    {this.renderAddBoard()}
                </div>
        }
        return (
            renderContainer
        )
    }
}

export default ProjectView;

import React from 'react';
import BoardView from '../views/BoardView';
import {ColumnService} from '../../services/ColumnService';

class Board extends React.Component {
    constructor(props) {
        super(props)
        this.boardReference = this.props.boardReference;
        this.columnService = new ColumnService();
        this.state = {
            columns: [],
            isHidden: this.props.isHidden
        }
    }

    componentDidMount() {
        this.setDatabaseListener();
    }

    handleSubmit = (columnName, order) => {
        this.columnService.addColumn(columnName, order, this.boardReference);
    }

    handleEdit = (name, newColumnName, newColumnOrder) => {
        this.columnService.editColumn(name, newColumnName, newColumnOrder, this.boardReference);
    }

    handleDelete = data => {
        const name = data.id;
        this.columnService.deleteColumn(name, this.boardReference);
    }

    render() {
        return (
            <BoardView
                isHidden={this.state.isHidden}
                columns={this.state.columns}
                handleSubmit={this.handleSubmit}
                handleEdit={this.handleEdit}
                handleDelete={this.handleDelete}
            />
        )
    }

    setDatabaseListener() {
        this.columnService.columnRef(this.boardReference).onSnapshot(data => {
            const listOfFetchedColumns = [];
            data.docs.forEach(doc => {
                const columnReference = doc.ref;
                const data = doc.data();
                data['ref'] = columnReference;
                listOfFetchedColumns.push(data);
                console.log('fetched columns', data);
            });
            listOfFetchedColumns.sort((a, b) => (a.order > b.order) ? 1 : -1)
            this.setState({
                columns: listOfFetchedColumns
            });
        });
    }
}

export default Board;

import React from 'react';
import {Button} from "react-bootstrap";
import TextField from '@material-ui/core/TextField';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import Column from "../controllers/Column";

require("../../styles/Board.css");
require("../../styles/Column.css");

class BoardView extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            render: false,
            modalShow: false,
            modalAddShow: false,
            modalColumn: "",
            columnName: "",
            columnOrder: "",
            newName: "",
            newOrder: "",
            validate: true,
            hideColumns: true,
            isHidden: this.props.isHidden
        };
        this.handleChange = this.handleChange.bind(this);
    }

    renderColumns = () => {
        if (this.props.columns.length === 0) {
            return (<div className="no-content">Brak kolumn!</div>)
        }

        return this.props.columns.map(column =>
            this.renderColumn(column)
        );
    };

    renderModal = (column) => {
        this.setState({
            modalShow: true,
            modalColumn: column,
            newName: column.name,
            newOrder: column.order
        })
    };

    renderColumn = (column) => {
        const handleClose = () => {
            this.setState({
                modalShow: false,
                newName: "",
                newOrder: ""
            })
        };

        const handleEdit = () => {
            handleClose();
            this.props.handleEdit(this.state.modalColumn.name, this.state.newName, parseInt(this.state.newOrder));
            this.setState({
                modalColumn: ""
            });
        };

        return (
            <div className="column">
                <div className="bookmark column-head">
                    {column.name}
                    <Button
                        className="action-button delete"
                        id={column.name}
                        onClick={this.handleDelete}
                        variant="danger"
                    >
                        X
                    </Button>
                    <Button
                        className="action-button edit"
                        id={column.name}
                        onClick={() => this.renderModal(column)}
                        variant="warning"
                    >
                        O
                    </Button>
                    <Dialog open={this.state.modalShow} aria-labelledby="form-dialog-title">
                        <DialogTitle id="form-dialog-title">Edytuj kolumnę {this.state.modalColumn.name}</DialogTitle>
                        <DialogContent>
                            <TextField
                                autoFocus
                                margin="dense"
                                name="newName"
                                label="Nazwa kolumny"
                                type="text"
                                onChange={this.handleChange}
                                value={this.state.newName}
                                fullWidth
                            />
                            <TextField
                                autoFocus
                                margin="dense"
                                name="newOrder"
                                label="Kolejność kolumny"
                                type="number"
                                min={1}
                                onChange={this.handleChange}
                                value={this.state.newOrder}
                                fullWidth
                            />
                        </DialogContent>
                        <DialogActions>
                            <Button onClick={handleClose} color="primary">
                                Anuluj
                            </Button>
                            <Button onClick={handleEdit}
                                    disabled={
                                        this.state.newName === "" ||
                                        this.state.newOrder === "" ||
                                        this.state.newOrder < 0 ||
                                        !this.state.validate
                                    }
                                    color="primary">
                                Zapisz
                            </Button>
                        </DialogActions>
                    </Dialog>
                </div>
                <Column columnReference={column.ref} name={column.name}/>
            </div>
        )
    };

    renderAddModal = () => {
        this.setState({
            modalAddShow: true,
        })
    };

    renderAddColumn = () => {
        const handleClose = () => {
            this.setState({
                modalAddShow: false,
                newName: ""
            })
        };

        const handleAdd = () => {
            this.props.handleSubmit(this.state.columnName, parseInt(this.state.columnOrder));
            this.setState({columnName: "", columnOrder: ""});
            handleClose();
            this.setState({
                modalColumn: ""
            });
        };

        return (
            <div className="new-column-button-wrapper">
                <Button
                    className="add-button new-column"
                    onClick={this.renderAddModal}
                    variant="success"
                >
                    +
                </Button>
                <Dialog open={this.state.modalAddShow} aria-labelledby="form-dialog-title">
                    <DialogTitle id="form-dialog-title">Dodaj kolumnę</DialogTitle>
                    <DialogContent>
                        <TextField
                            autoFocus
                            margin="dense"
                            name="columnName"
                            label="Nazwa kolumny"
                            type="text"
                            onChange={this.handleChange}
                            value={this.state.columnName}
                            fullWidth
                        >
                        </TextField>
                        <TextField
                            margin="dense"
                            name="columnOrder"
                            label="Kolejność"
                            type="number"
                            min={1}
                            onChange={this.handleChange}
                            value={this.state.columnOrder}
                            fullWidth
                        >
                        </TextField>
                    </DialogContent>
                    <DialogActions>
                        <Button onClick={handleClose} color="primary">
                            Anuluj
                        </Button>
                        <Button onClick={handleAdd} disabled={
                            this.state.columnName === "" ||
                            this.state.columnOrder === "" ||
                            this.state.columnOrder < 0 ||
                            !this.state.validate
                        } color="primary">
                            Dodaj
                        </Button>
                    </DialogActions>
                </Dialog>
            </div>
        );
    };

    handleDelete = e => {
        e.preventDefault();
        this.props.handleDelete(e.target);
    };

    handleChange = e => {
        e.preventDefault();
        const isValid = this.validator(e.target)
        this.setState({
            [e.target.name]: e.target.value,
            validate: isValid
        });
    };

    validator = input => {
        if (input.name === "newName" && this.state.modalColumn.name === input.value)
            return true
        const filter = this.props.columns.find(column =>
            column.name === input.value
        )
        return typeof (filter) === "undefined"
    }

    componentDidMount() {
        setTimeout(function () {
            this.setState({render: true})
        }.bind(this), 1000)
    }

    render() {
        let renderContainer = false;
        if (this.state.render) {
            renderContainer =
                <div className="board-body" hidden={this.state.isHidden}>
                    {this.renderColumns()}
                    {this.renderAddColumn()}
                </div>
        }
        return (
            renderContainer
        )
    }

}

export default BoardView;

this.setState(state => {
let oldValue = state.visibilityMap.get(board.name)
state.visibilityMap.set(board.name, !oldValue)
return state
 )};