这是反模式吗 - Reactjs
Is This An Anti-Pattern - Reactjs
我刚刚开始使用 React 并开发了一个小应用程序,同时我制作了一个小的显示和隐藏模态。我想知道我的做法是错误的。如果这是一个反模式,我应该怎么做?
class App extends Component {
constructor(props) {
super(props);
this.state = {show: false};
this.showModal = this.showModal.bind(this);
}
render() {
return (
<div>
<h2 className={styles.main__title}>Helloooo!</h2>
<Modal ref='show'/>
<button onClick={this.showModal} className={styles.addtask}>➕</button>
</div>
);
}
showModal(){
this.setState({
show: true
});
this.refs.show.showModal();
}
}
我制作的模态组件就是使用这个逻辑,它挂钩 dom 元素并使用 document.queryselector
进行修改。这是在 React 中进行 dom 操作的正确方法吗?
我用过的模态代码是这样的:
class Modal extends Component {
constructor() {
super();
this.hideModal = this.hideModal.bind(this);
this.showModal = this.showModal.bind(this);
this.state = { modalHook: '.'+styles.container };
}
render() {
return (
<div>
<div onClick={this.hideModal} className={styles.container}>
<div className={styles.container__content}>
<div className={styles.card}>
<div className={styles.card__header}>
<h2>Add new task</h2>
</div>
<div className={styles.card__main}>
<Input type="text" placeholder="enter the task title" />
<Input type="textarea" placeholder="enter the task details" />
</div>
<div className={styles.card__actions}>
</div>
</div>
</div>
</div>
</div>
);
}
showModal(){
let container = document.querySelector(this.state.modalHook);
container.classList.add(styles.show);
}
hideModal(e){
let container = document.querySelector(this.state.modalHook);
if(e.target.classList.contains(styles.container)){
container.classList.remove(styles.show);
}
}
}
您的示例看起来不错且简单,但是根据 this 最好不要过度使用 refs
。
并且它也可能有助于提升状态,如所述here。
这是我的例子:
class Modal extends React.Component {
constructor(props) {
super(props);
this.state = {show: props.show};
}
componentDidUpdate(prevProps, prevState) {
let modal = document.getElementById('modal');
if (prevProps.show) {
modal.classList.remove('hidden');
} else {
modal.className += ' hidden';
}
}
render() {
return (
<div id="modal" className={this.state.show ? '' : 'hidden'}>
My modal content.
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {show: false};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
show: !prevState.show
}));
}
render() {
return (
<div>
<button onClick={this.handleClick}>
Launch modal
</button>
<Modal show={this.state.show} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
在这里,我不假装最终的真理,而是尝试提供另一种选择,让您可以达到预期的结果。
要完成您需要的操作,您根本不需要使用 refs。您可以将状态作为道具传递给子组件。当状态更新时,道具将自动更新。然后你可以使用这个道具来切换 class。您可以在 jsbin here
上看到它的实际效果
const Modal = (props) => {
return (
<div className={props.show ? 'show' : 'hide'}>modal</div>
)
}
const styles = {
main__title: 'main__title',
addtask: 'addtask'
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {show: false};
this.toggleModal = this.toggleModal.bind(this);
}
render() {
return (
<div>
<h2 className={styles.main__title}>Helloooo!</h2>
<Modal show={this.state.show} />
<button onClick={this.toggleModal} className={styles.addtask}>➕</button>
</div>
);
}
toggleModal(){
this.setState({
show: !this.state.show
});
}
}
ReactDOM.render(<App />, document.getElementById('root'));
我刚刚开始使用 React 并开发了一个小应用程序,同时我制作了一个小的显示和隐藏模态。我想知道我的做法是错误的。如果这是一个反模式,我应该怎么做?
class App extends Component {
constructor(props) {
super(props);
this.state = {show: false};
this.showModal = this.showModal.bind(this);
}
render() {
return (
<div>
<h2 className={styles.main__title}>Helloooo!</h2>
<Modal ref='show'/>
<button onClick={this.showModal} className={styles.addtask}>➕</button>
</div>
);
}
showModal(){
this.setState({
show: true
});
this.refs.show.showModal();
}
}
我制作的模态组件就是使用这个逻辑,它挂钩 dom 元素并使用 document.queryselector
进行修改。这是在 React 中进行 dom 操作的正确方法吗?
我用过的模态代码是这样的:
class Modal extends Component {
constructor() {
super();
this.hideModal = this.hideModal.bind(this);
this.showModal = this.showModal.bind(this);
this.state = { modalHook: '.'+styles.container };
}
render() {
return (
<div>
<div onClick={this.hideModal} className={styles.container}>
<div className={styles.container__content}>
<div className={styles.card}>
<div className={styles.card__header}>
<h2>Add new task</h2>
</div>
<div className={styles.card__main}>
<Input type="text" placeholder="enter the task title" />
<Input type="textarea" placeholder="enter the task details" />
</div>
<div className={styles.card__actions}>
</div>
</div>
</div>
</div>
</div>
);
}
showModal(){
let container = document.querySelector(this.state.modalHook);
container.classList.add(styles.show);
}
hideModal(e){
let container = document.querySelector(this.state.modalHook);
if(e.target.classList.contains(styles.container)){
container.classList.remove(styles.show);
}
}
}
您的示例看起来不错且简单,但是根据 this 最好不要过度使用 refs
。
并且它也可能有助于提升状态,如所述here。
这是我的例子:
class Modal extends React.Component {
constructor(props) {
super(props);
this.state = {show: props.show};
}
componentDidUpdate(prevProps, prevState) {
let modal = document.getElementById('modal');
if (prevProps.show) {
modal.classList.remove('hidden');
} else {
modal.className += ' hidden';
}
}
render() {
return (
<div id="modal" className={this.state.show ? '' : 'hidden'}>
My modal content.
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {show: false};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
show: !prevState.show
}));
}
render() {
return (
<div>
<button onClick={this.handleClick}>
Launch modal
</button>
<Modal show={this.state.show} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
在这里,我不假装最终的真理,而是尝试提供另一种选择,让您可以达到预期的结果。
要完成您需要的操作,您根本不需要使用 refs。您可以将状态作为道具传递给子组件。当状态更新时,道具将自动更新。然后你可以使用这个道具来切换 class。您可以在 jsbin here
上看到它的实际效果const Modal = (props) => {
return (
<div className={props.show ? 'show' : 'hide'}>modal</div>
)
}
const styles = {
main__title: 'main__title',
addtask: 'addtask'
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {show: false};
this.toggleModal = this.toggleModal.bind(this);
}
render() {
return (
<div>
<h2 className={styles.main__title}>Helloooo!</h2>
<Modal show={this.state.show} />
<button onClick={this.toggleModal} className={styles.addtask}>➕</button>
</div>
);
}
toggleModal(){
this.setState({
show: !this.state.show
});
}
}
ReactDOM.render(<App />, document.getElementById('root'));