javascript - 引用特定列的引用数组存在问题
问题描述
我无法refs
工作。我想渲染几列,然后渲染放置在右列上的项目。例如,声明的 items:const items = [0, 2, 5]
应该像这样在网格上呈现(假设第一列的索引为 0):
我想refs
在列上使用来获取列位置(使用 getBoundingClientRect() 只是为了这个想法)但是columnsRefs[index].current
即使componentDidMount
按照推荐的方式分配了参考,我也是空的。这是我的代码:
import * as React from 'react';
export const GridColumn = (props: {forwardedRef?: any }) => (
<div style={{borderRight: "1px solid #ababab", width: "20px", height: "200px"}} ref={props.forwardedRef}></div>
);
interface GridProps {
}
export class Grid extends React.Component<GridProps, any> {
public constructor(props: GridProps) {
super(props);
this.state = {
columns: []
}
}
private columnRefs = new Array<React.RefObject<HTMLDivElement>>();
public componentDidMount(){
// setup the columns with refs
const columnIds = [0, 1, 2, 3, 4, 5, 6, 7];
const columns = columnIds.map(id => {
const ref = React.createRef<HTMLDivElement>();
this.columnRefs.push(ref);
return (<GridColumn forwardedRef={ref}/>)
});
this.setState({columns: columns});
}
public render() {
// setup the items
const items = [
0, 2, 5
]
let elements = items.map(item => {
if(this.columnRefs[item] && this.columnRefs[item].current) {
return (
<div style={{backgroundColor: "blue",
opacity: 0.5,
position: "absolute",
width: "10px",
height: "20px",
left: `${this.columnRefs[item].current.getBoundingClientRect().left}px`,
top: "0"}}>
</div>);
}
else {
return undefined;
}
});
return (
<div style={{width: "500px", height: "200px", position: "relative"}}>
{elements}
<div style={{display: "flex"}}>
{this.state.columns}
</div>
</div>);
}
}
我做错了什么,以至于条件render
if(this.columnRefs[item] && this.columnRefs[item].current)
总是错误的?
解决方案
您不应该将渲染的组件存储在状态中。状态用于您要转换为标记的数据。这是带有注释的修改代码:
// Now component properly forwards ref
const GridColumn = React.forwardRef((props, ref) => (
<div
style={{ borderRight: "1px solid #ababab", width: "20px", height: "200px" }}
ref={ref}
{...props}
></div>
));
class Grid extends React.Component {
constructor(props) {
super(props);
this.state = {
columns: [1,2,3,4,5,6,7,8,9],
rendered: false
};
}
// When you want to use collection of refs, you can set up your own storage for them
// I use Set because it will prevent duplicates
// It is important that when component will be removed it's ref will turn into `null`, so you will have to check if your div still exists
columnRefs = new Set();
componentDidUpdate() {
// you will see your refs set in console on each render
console.debug(this.columnRefs);
}
componentDidMount() {
// You need to rerender to render something from refs
this.setState({rendered: true});
}
render() {
const items = [0, 2, 5];
let elements = items.map((item) => {
// turn set into array and filter out null
let refArray = [...this.columnRefs].filter(Boolean);
if (refArray[item]) {
return (
<div
key={item}
style={{
backgroundColor: "blue",
opacity: 0.5,
position: "absolute",
width: "10px",
height: "20px",
left: `${refArray[item].getBoundingClientRect().left}px`,
top: "0",
}}
></div>
);
} else {
return undefined;
}
});
return (
<div style={{ width: "500px", height: "200px", position: "relative" }}>
{elements}
<div style={{ display: "flex" }}>
{/* We use here ref callback to store forwarded ref into out set */}
{this.state.columns.map((item) => (
<GridColumn key={item} ref={(ref) => this.columnRefs.add(ref)} />
))}
</div>
</div>
);
}
}
读什么:
例子
可重现且部分固定的示例:https ://jsfiddle.net/moL1sbzj/
推荐阅读
- javascript - 在 react native 中使用 createMaterialTopTabNavigator 时无法导航到另一个页面
- java - 为 lambda 表达式中的异常生成函数接口并将它们抛出到方法的签名上
- vim - 如何使用 VimL 脚本向当前 Vim 缓冲区添加一些行?
- python - AttributeError:“矩形”对象没有属性“左”
- javascript - 我使用的是纯 JavaScript,但我继续收到以“不是函数”结尾的错误。如何做到这一点,以便我可以检测单词并做出相应的回复?
- android - Android 键盘在页面上移动内容
- html - 更改导航栏以居中标题折叠的屏幕宽度
- multi-touch - Java Robot 的多点触控手势
- github - Heroku GIT 部署失败 (yarn.lock)
- node.js - CredentialsProviderError:无法从任何提供者 nodejs aws 错误加载凭据