我是ReactJS和Context API / Hook的新手。我有一个基本的应用程序,其中父功能组件将值传递给3个按钮。但是问题是我在按钮上看到默认值(“欢迎”),而不是在上下文中设置的值。
Context.js:
import React, { useState, useContext, useReducer } from 'react';
const initalDBStates = {Couchbase:[],MongoDB:[],Cassandra:[], jobId: null, results:[],activeDBName: "Welcome"}
export const AppContext = React.createContext(initalDBStates);
TestGrid.js:
import React, { useState, useContext, useReducer } from 'react';
import DBButton from './DBButton';
import {AppContext} from "./Context";
const TestGrid = () => {
const context = useContext(AppContext)
const setActiveDBName = (activeDBName) => {
setDBState({...dbState, activeDBName: activeDBName})
}
const [dbState,setDBState] = useState({...context, updateJobId:updateJobId,updateResults:updateResults,setActiveDBName:setActiveDBName })
return(
<AppContext.Provider value={dbState}>
<div class="dls-gray-02-bg pad " style={{height: '100%', minHeight: '100vh',}}>
<div class="row stack-a">
<div class="display-inline-block">
<DBButton onClick={()=>setActiveDBName("Couchbase")}/>
<DBButton onClick={()=>setActiveDBName("Cassandra")}/>
<DBButton onClick={()=>setActiveDBName("MongoDB")}/>
</div>
</div>
</div>
</AppContext.Provider>
)
}
export default TestGrid;
最终DBBUtton.js:
import React, { useContext } from 'react';
import {AppContext} from "./Context";
const colors = {"Couchbase":"deep-blue", "MongoDB":"green","Cassandra":"bright-blue"};
function DBButton() {
return(
<AppContext.Consumer>
{
(value) => {
let buttonClassName = "btn btn-contextual dls-" + colors[value.activeDBName];
let padClassName = "pad-3 dls-"+ colors[value.activeDBName] + "-bg";
return(
<div className="margin-b">
<div className={padClassName}>
<button className={buttonClassName}>{value.activeDBName}</button>
</div>
</div>)
}
}
</AppContext.Consumer>
)
}
export default DBButton;
这3个按钮应该显示Couchbase,Cassandra和MongoDB,但是它们显示的是默认白色和用于初始化上下文的“ Welcome”默认值。有人可以帮我吗?无法弄清楚我在做什么错!
答案 0 :(得分:2)
您的项目目前的运行方式:
您正在使用“ Welcome”作为activeDBName初始化上下文,并且将按钮设置为显示activeDBName的当前值,这就是为什么它们都显示“ Welcome”的原因。您正在传递一个方法来将activeDBName的值更改为每个按钮的道具,称为“ onClick”,但是按钮组件未使用onClick道具(或任何道具),因此单击按钮时没有任何反应
如果更改代码以使按钮组件将props.onClick传递给实际的<button>
元素作为其onClick道具,则单击按钮将调用setActiveDBName方法并将activeDBName设置为给定值。单击最上面的按钮会将activeDBName更改为“ Couchbase”,并且由于按钮组件显示了activeDBName的当前值,因此这将导致所有三个按钮都显示“ Couchbase”。如果单击第二个按钮,则所有三个按钮将显示“ Cassandra”。
要使每个按钮显示其自己的文本,您需要将一个道具传递给按钮以告诉它应显示的内容,然后在按钮文本中使用该道具。 (您也可以使用此道具动态生成按钮的onClick函数。)
您还应该在react元素上使用className
而不是class
。
我假设您还没有包括一些其他CSS,因为当前唯一应用的样式是在TestGrid的div上的style={{height: '100%', minHeight: '100vh',}}
上。
我整理了一个沙箱,其中显示了我上面提到的更改以及一个有效的示例:https://codesandbox.io/s/sweet-kilby-zomb6?file=/src/DBButton.js