Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.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 反应上下文api-上下文更改后使用者不会重新呈现_Javascript_Reactjs_Typescript_React Context - Fatal编程技术网

Javascript 反应上下文api-上下文更改后使用者不会重新呈现

Javascript 反应上下文api-上下文更改后使用者不会重新呈现,javascript,reactjs,typescript,react-context,Javascript,Reactjs,Typescript,React Context,我在寻找答案,但没有找到任何答案,所以我在这里问, 我有一个消费者可以更新上下文, 和另一个应该显示上下文的使用者。 我正在使用react with typescript(16.3) 上下文(AppContext.tsx): 制作人(App.tsx): interface Props{} 类应用程序扩展了React.Component{ 状态:AppContext=appContextInitialState; 建造师(道具:道具){ 超级(道具); } render(){ 返回( ); } }

我在寻找答案,但没有找到任何答案,所以我在这里问, 我有一个消费者可以更新上下文, 和另一个应该显示上下文的使用者。 我正在使用react with typescript(16.3)

上下文(AppContext.tsx):

制作人(App.tsx):

interface Props{}
类应用程序扩展了React.Component{
状态:AppContext=appContextInitialState;
建造师(道具:道具){
超级(道具);
}
render(){
返回(
);
}
}
导出默认应用程序;
更新上下文使用者(SubmitTransactionFile.tsx)

类SubmitTransactionFile扩展React.Component{
私有fileLoadedEvent(文件:React.ChangeEvent,上下文:AppContext):void{
让files=file.target.files;
let reader=new FileReader();
如果(文件和文件[0]){
reader.readAsText(文件[0]);
reader.onload=(json)=>{
if(json&&json.target){
//@ts ignore->这是因为typescript编译器无法识别结果字段
setJsonTran(JSON.parse(JSON.target.result))
}
}
}
}
render(){
返回(
{context=>
选择事务文件
this.fileLoadedEvent(文件,上下文)}/> {context.jsonTransactions}

} ) } } 导出默认提交的事务文件;
最后是显示消费者(取款交易表.tsx):

类撤销TransactionTable扩展了React.Component{
render(){
返回(
{context=>
{context.jsonTransactions}
}
)
}
}
导出默认取款交易表;
我的理解是,在
fileLoadedEvent
之后,函数被称为
上下文。setJsonTran
应该重新呈现其他使用者,而
取款交易表
组件应该重新呈现,但它没有


我做错了什么?

当您更新状态时,不会触发提供者的重新呈现,因此消费者数据不会更改。您应该使用setState更新状态,并将上下文值分配给提供程序

class App extends React.Component<Props, AppContext> {
  constructor(props : Props) {
    super(props);
    this.state = {
         jsonTransactions: null,
         setJsonTran: this.setJsonTran
    };
  }

  setJsonTran : (data: WithdrawTransactionsElement) => {
        this.setState({
             jsonTransactions: data
        });
  }

  render() {
    return (
        <AppContext.Provider value={this.state}>
          <div className="App">
            <header className="App-header">
              <SubmitTransactionFile/>
              <WithdrawTransactionsTable />
            </header>
          </div>
        </AppContext.Provider>
    );
  }
}

export default App;
类应用程序扩展了React.Component{
建造师(道具:道具){
超级(道具);
此.state={
jsonTransactions:null,
setJsonTran:this.setJsonTran
};
}
setJsonTran:(数据:取款事务元素)=>{
这是我的国家({
jsonTransactions:数据
});
}
render(){
返回(
);
}
}
导出默认应用程序;

您的
设置JSONTRAN
只是改变上下文的默认值,而不会导致提供给
提供者的
值发生更改

相反,您可以将
jsonTransactions
保持在最顶层状态,并传递一个函数,该函数将更改此状态,然后更新

示例

const AppContext = React.createContext();

class App extends React.Component {
  state = {
    jsonTransactions: null
  };

  setJsonTran = data => {
    this.setState({ jsonTransactions: data });
  };

  render() {
    const context = this.state;
    context.setJsonTran = this.setJsonTran;

    return (
      <AppContext.Provider value={context}>
        <div className="App">
          <header className="App-header">
            <SubmitTransactionFile />
            <WithdrawTransactionsTable />
          </header>
        </div>
      </AppContext.Provider>
    );
  }
}
const-AppContext=React.createContext();
类应用程序扩展了React.Component{
状态={
jsonTransactions:null
};
setJsonTran=data=>{
this.setState({jsonTransactions:data});
};
render(){
const context=this.state;
context.setJsonTran=this.setJsonTran;
返回(
);
}
}
const-AppContext=React.createContext();
类应用程序扩展了React.Component{
状态={
jsonTransactions:null
};
setJsonTran=data=>{
this.setState({jsonTransactions:data});
};
render(){
const context=this.state;
context.setJsonTran=this.setJsonTran;
返回(
);
}
}
类SubmitTransactionFile扩展了React.Component{
fileLoadedEvent(文件、上下文){
让files=file.target.files;
let reader=new FileReader();
如果(文件和文件[0]){
reader.readAsText(文件[0]);
reader.onload=json=>{
if(json&&json.target){
//在本例中,切片只是为了不输出太多
setJsonTran(json.target.result.slice(0,10));
}
};
}
}
render(){
返回(
{context=>(
选择事务文件

this.fileLoadedEvent(文件,上下文)} /> {context.jsonTransactions}

)} ); } } 类TransactionTable扩展React.Component{ render(){ 返回( {context=>( {context.jsonTransactions} )} ); } } render(,document.getElementById(“根”))


这有助于我了解我的问题。在我的例子中,我使用上下文来表示数组。当我尝试推送或拼接阵列并将其返回到我的reducer中时,React不会将其视为更新。我通过将数组嵌套为上下文状态中的属性来解决我的问题,如{myArray:[]}。正是你使用的“变异”一词让我意识到我忽略了什么。。。谢谢这可能不是OP的原因,但我有一个非常类似的问题。在我的例子中,我不小心在一个嵌套组件中包含了另一个AppContext.Provider。这是一种扭曲的行为,因为任何更深层次的孩子都没有和专业人士说话
class SubmitTransactionFile extends React.Component {

    private fileLoadedEvent(file: React.ChangeEvent<HTMLInputElement>, context: AppContext): void{
        let files = file.target.files;
        let reader = new FileReader();
        if (files && files[0]) {
            reader.readAsText(files[0]);
            reader.onload = (json) =>  {
                if (json && json.target) {
                    // @ts-ignore -> this is because result field is not recognized by typescript compiler
                    context.setJsonTran(JSON.parse(json.target.result))
                }
            }
        }
    }

    render() {
        return (
            <AppContext.Consumer>
                { context  =>
                    <div className="SubmitTransactionFile">
                        <label>Select Transaction File</label><br />
                        <input type="file" id="file" onChange={(file) =>
                            this.fileLoadedEvent(file, context)} />
                        <p>{context.jsonTransactions}</p>
                    </div>
                }
            </AppContext.Consumer>
        )
    }
}


export default SubmitTransactionFile;
class WithdrawTransactionsTable extends React.Component {

    render() {
        return (
            <AppContext.Consumer>
                { context  =>
                    <div>
                        <label>{context.jsonTransactions}</label>
                    </div>
                }
            </AppContext.Consumer>
        )
    }
}

export default WithdrawTransactionsTable;
class App extends React.Component<Props, AppContext> {
  constructor(props : Props) {
    super(props);
    this.state = {
         jsonTransactions: null,
         setJsonTran: this.setJsonTran
    };
  }

  setJsonTran : (data: WithdrawTransactionsElement) => {
        this.setState({
             jsonTransactions: data
        });
  }

  render() {
    return (
        <AppContext.Provider value={this.state}>
          <div className="App">
            <header className="App-header">
              <SubmitTransactionFile/>
              <WithdrawTransactionsTable />
            </header>
          </div>
        </AppContext.Provider>
    );
  }
}

export default App;
const AppContext = React.createContext();

class App extends React.Component {
  state = {
    jsonTransactions: null
  };

  setJsonTran = data => {
    this.setState({ jsonTransactions: data });
  };

  render() {
    const context = this.state;
    context.setJsonTran = this.setJsonTran;

    return (
      <AppContext.Provider value={context}>
        <div className="App">
          <header className="App-header">
            <SubmitTransactionFile />
            <WithdrawTransactionsTable />
          </header>
        </div>
      </AppContext.Provider>
    );
  }
}