我如何在react.js中选择某些酒吧?
这是我的代码:
var Progressbar = React.createClass({
getInitialState: function () {
return { completed: this.props.completed };
},
addPrecent: function (value) {
this.props.completed += value;
this.setState({ completed: this.props.completed });
},
render: function () {
var completed = this.props.completed;
if (completed < 0) { completed = 0 };
return (...);
}
我想使用这个React组件:
var App = React.createClass({
getInitialState: function () {
return { baction: 'Progress1' };
},
handleChange: function (e) {
var value = e.target.value;
console.log(value);
this.setState({ baction: value });
},
handleClick10: function (e) {
console.log('You clicked: ', this.state.baction);
document.getElementById(this.state.baction).addPrecent(10);
},
render: function () {
return (
<div class="center">Progress Bars Demo
<Progressbar completed={25} id="Progress1" />
<h2 class="center"></h2>
<Progressbar completed={50} id="Progress2" />
<h2 class="center"></h2>
<Progressbar completed={75} id="Progress3" />
<h2 class="center"></h2>
<span>
<select name='selectbar' id='selectbar' value={this.state.baction} onChange={this.handleChange}>
<option value="Progress1">#Progress1</option>
<option value="Progress2">#Progress2</option>
<option value="Progress3">#Progress3</option>
</select>
<input type="button" onClick={this.handleClick10} value="+10" />
<button>+25</button>
<button>-10</button>
<button>-25</button>
</span>
</div>
)
}
});
我想执行handleClick10函数,并对所选的进度条执行操作。
但我得到的结果是
You clicked: Progress1
TypeError: document.getElementById(...) is null
如何在react.js中选择特定的元素?
你可以通过指定ref来实现
编辑:在react v16.8.0的函数组件中,你可以用useRef定义一个引用。注意,当你在函数组件上指定一个ref时,你需要使用React。将引用转发给使用useImperativeHandle的DOM元素,以从函数组件中公开某些函数
Ex:
const Child1 = React.forwardRef((props, ref) => {
return <div ref={ref}>Child1</div>
});
const Child2 = React.forwardRef((props, ref) => {
const handleClick= () =>{};
useImperativeHandle(ref,() => ({
handleClick
}))
return <div>Child2</div>
});
const App = () => {
const child1 = useRef(null);
const child2 = useRef(null);
return (
<>
<Child1 ref={child1} />
<Child1 ref={child1} />
</>
)
}
编辑:
在React 16.3+中,使用React. createref()创建ref:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
为了访问元素,使用:
const node = this.myRef.current;
使用React.createRef()的DOC
EDIT
然而,facebook不建议这样做,因为字符串引用有一些问题,被认为是遗留问题,很可能在未来的版本中被删除。
从文档中可以看出:
遗留API:字符串引用
如果你以前用过React,你可能会
熟悉旧的API,其中ref属性是一个字符串,例如
"textInput", DOM节点被访问为this.ref .textInput。我们
建议反对,因为字符串引用有一些问题,被考虑
遗留的,并且很可能在未来的版本中被删除。如果
你目前正在使用this.ref . textinput来访问引用,我们
建议改用回调模式。
对于React 16.2或更早的版本,建议使用回调模式:
<Progressbar completed={25} id="Progress1" ref={(input) => {this.Progress[0] = input }}/>
<h2 class="center"></h2>
<Progressbar completed={50} id="Progress2" ref={(input) => {this.Progress[1] = input }}/>
<h2 class="center"></h2>
<Progressbar completed={75} id="Progress3" ref={(input) => {this.Progress[2] = input }}/>
使用回调的DOC
甚至老版本的react也使用如下所示的字符串定义refs
<Progressbar completed={25} id="Progress1" ref="Progress1"/>
<h2 class="center"></h2>
<Progressbar completed={50} id="Progress2" ref="Progress2"/>
<h2 class="center"></h2>
<Progressbar completed={75} id="Progress3" ref="Progress3"/>
为了得到元素,只要做
var object = this.refs.Progress1;
记住在箭头函数块中使用:
print = () => {
var object = this.refs.Progress1;
}
等等……
在更新的React版本中,你可以通过这样的钩子来使用和操作DOM:
import React, { useEffect, useRef } from "react";
const MyComponent = () => {
const myContainer = useRef(null);
useEffect(() => {
console.log("myContainer..", myContainer.current);
});
return (
<>
<h1>Ref with react</h1>
<div ref={myContainer}>I can use the DOM with react ref</div>
</>
);
};
export default MyComponent;
无论何时你想访问你的DOM元素,只要使用myContainer.current
在我的例子中,我不能使用ref,因为元素是在许多子组件之间的某个地方,我必须通过类和id而不是ref访问它们。所以,尝试使用useEffect钩子没有工作,因为它找不到元素:
useEffect(() => {
const el1 = document.querySelector('.el1')
const el2 = document.querySelector('.el2')
}, [])
元素是未定义的,因为当它被安装时,子组件也不会在父组件之前被安装。
我所做的就是使用timeout:
useEffect(() => {
const timer = setTimeout(() => {
const el1 = document.querySelector('.el1')
const el2 = document.querySelector('.el2')
},500)
return () => {
clearTimeout(timer)
}
}, [])
现在,它运行得很好。它找到了DOM,我就可以操纵它们了。希望这能帮助到别人!
你可以通过指定ref来实现
编辑:在react v16.8.0的函数组件中,你可以用useRef定义一个引用。注意,当你在函数组件上指定一个ref时,你需要使用React。将引用转发给使用useImperativeHandle的DOM元素,以从函数组件中公开某些函数
Ex:
const Child1 = React.forwardRef((props, ref) => {
return <div ref={ref}>Child1</div>
});
const Child2 = React.forwardRef((props, ref) => {
const handleClick= () =>{};
useImperativeHandle(ref,() => ({
handleClick
}))
return <div>Child2</div>
});
const App = () => {
const child1 = useRef(null);
const child2 = useRef(null);
return (
<>
<Child1 ref={child1} />
<Child1 ref={child1} />
</>
)
}
编辑:
在React 16.3+中,使用React. createref()创建ref:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
为了访问元素,使用:
const node = this.myRef.current;
使用React.createRef()的DOC
EDIT
然而,facebook不建议这样做,因为字符串引用有一些问题,被认为是遗留问题,很可能在未来的版本中被删除。
从文档中可以看出:
遗留API:字符串引用
如果你以前用过React,你可能会
熟悉旧的API,其中ref属性是一个字符串,例如
"textInput", DOM节点被访问为this.ref .textInput。我们
建议反对,因为字符串引用有一些问题,被考虑
遗留的,并且很可能在未来的版本中被删除。如果
你目前正在使用this.ref . textinput来访问引用,我们
建议改用回调模式。
对于React 16.2或更早的版本,建议使用回调模式:
<Progressbar completed={25} id="Progress1" ref={(input) => {this.Progress[0] = input }}/>
<h2 class="center"></h2>
<Progressbar completed={50} id="Progress2" ref={(input) => {this.Progress[1] = input }}/>
<h2 class="center"></h2>
<Progressbar completed={75} id="Progress3" ref={(input) => {this.Progress[2] = input }}/>
使用回调的DOC
甚至老版本的react也使用如下所示的字符串定义refs
<Progressbar completed={25} id="Progress1" ref="Progress1"/>
<h2 class="center"></h2>
<Progressbar completed={50} id="Progress2" ref="Progress2"/>
<h2 class="center"></h2>
<Progressbar completed={75} id="Progress3" ref="Progress3"/>
为了得到元素,只要做
var object = this.refs.Progress1;
记住在箭头函数块中使用:
print = () => {
var object = this.refs.Progress1;
}
等等……
免责声明:虽然上面的答案可能是一个更好的解决方案,但作为初学者,当你想要的只是一些非常简单的东西时,你需要接受很多东西。这是为了更直接地回答你最初的问题“我如何在React中选择某些元素”
我认为你的问题中的困惑是因为你有React组件,你正在传递id“Progress1”,“Progress2”等。我相信这不是设置html属性“id”,而是React组件属性。如。
class ProgressBar extends React.Component {
constructor(props) {
super(props)
this.state = {
id: this.props.id <--- ID set from <ProgressBar id="Progress1"/>
}
}
}
正如上面提到的一些答案,你绝对可以使用document。querySelector在你的React应用程序内部,但你必须清楚,它是选择html输出组件的渲染方法。假设你的渲染输出是这样的:
render () {
const id = this.state.id
return (<div id={"progress-bar-" + id}></div>)
}
然后你可以在其他地方做一个正常的javascript querySelector调用,像这样:
let element = document.querySelector('#progress-bar-Progress1')