Javascript 如何在用户将新行保存到数据库后重新加载表

Javascript 如何在用户将新行保存到数据库后重新加载表,javascript,reactjs,Javascript,Reactjs,当组件最初加载时,它向数据库发出get请求,以使用初始数据构建表。这个很好用。然后,该表由子组件组成。然后,包含数据的组件具有更新和删除按钮。然后加载最后一个子组件,没有数据,只有空白输入和保存按钮。当用户单击“保存”或“删除”时,我希望重新呈现该表以反映这些更改。这就是我被困的地方 我尝试在单击这些按钮后调用axios.get方法,更改状态forceRender(),但没有一个会重新加载父组件 class ParentComp extends Component{ state={ so

当组件最初加载时,它向数据库发出get请求,以使用初始数据构建表。这个很好用。然后,该表由子组件组成。然后,包含数据的组件具有更新和删除按钮。然后加载最后一个子组件,没有数据,只有空白输入和保存按钮。当用户单击“保存”或“删除”时,我希望重新呈现该表以反映这些更改。这就是我被困的地方

我尝试在单击这些按钮后调用axios.get方法,更改状态forceRender(),但没有一个会重新加载父组件

class ParentComp extends Component{
 state={
   something:null
 }
reloadTable=()=>{
   this.setState(something:something);
} 
render(){ 
   return(
      <ChildComp actionForReloadTable={this.reloadTable}....></ChildComp>
     ) 
}
母公司

class ParentComp extends Component{
    constructor(props){
      super(props)
      this.handler = this.handler.bind(this);
      this.state = {
        data: [],
        loading: false,
        newInput: false,
      }
    }

    componentDidMount(){
      this.GetData();
    }

    handler(){
      this.setState({newInput: true});
      console.log("Called");
    } 


    GetData(){
      axios.defaults.baseURL = 'http://127.0.0.1:8000/api/';
      const header = {
        headers:{
          'Authorization': "Bearer " + sessionStorage.getItem('JWTAccess')
        }
      }
      axios.get("tableData/", header)
          .then(response => {
            this.setState({data: response.data,
              loading: true
            });
            console.log(this.state.expenses);
          })
          .catch(error => {
            console.log(error);
      })
    }

    render(){
        return(
          <div>
            <table>
            <tbody>
              <tr>
                <th>Name</th>
                <th>Value</th>
              </tr>
                {this.state.data.map(
                expenses => {
                return(                
                 <ChildComp key={Math.random()} name={data.title} dataId={data.id} value={data.value} empty={false} action={this.handler}/>                 
                );
                }
                )}
                < ChildComp key={Math.random()} name={''} dataId={''} value={''} empty={true} action={this.handler}/>
              </tbody>
            </table>
          </div>
        );
      }
  }
export default ParentComp;
类ParentComp扩展组件{ 建造师(道具){ 超级(道具) this.handler=this.handler.bind(this); 此.state={ 数据:[], 加载:false, newInput:false, } } componentDidMount(){ 这是GetData(); } handler(){ this.setState({newInput:true}); 控制台日志(“调用”); } GetData(){ axios.defaults.baseURL='0http://127.0.0.1:8000/api/'; 常数头={ 标题:{ “授权”:“承载者”+会话存储.getItem('JWTAccess') } } get(“tableData/”,标题) 。然后(响应=>{ this.setState({data:response.data, 加载:正确 }); console.log(this.state.expenses); }) .catch(错误=>{ console.log(错误); }) } render(){ 返回( 名称 价值 {this.state.data.map( 费用=>{ 报税表( ); } )} ); } } 导出默认ParentComp; 具有axios调用之一的子组件(不向线程发送垃圾邮件):

类childComp扩展组件{
建造师(道具){
超级(道具)
this.handleSubmit=this.handleSubmit.bind(this);
this.handlePut=this.handlePut.bind(this);
this.handleDelete=this.handleDelete.bind(this);
this.handleButtons=this.handleButtons.bind(this);
this.action=this.handleButtons.bind(this);
此.state={
dataId:this.props.dataId,
名称:this.props.name,
value:this.props.value,
空的:这个。道具。空的
}
}
PostData(){
axios.defaults.baseURL='0http://127.0.0.1:8000/api/';
常数头={
标题:{
“授权”:“承载者”+会话存储.getItem('JWTAccess')
}
}
常数有效载荷={
标题:this.state.name,
成本:这个.state.value
}
axios.post(“tableData/”,有效负载,标题)
。然后(响应=>{
控制台日志(响应);
})
.catch(错误=>{
console.log(错误);
})
}
handleDelete(){
这是DeleteData();
this.props.action();
}
handlePut(){
这个.PutData();
}
handleSubmit(){
这是PostData();
this.props.action();
}
车把扣(){
if(this.state.empty){
返回(
拯救
)
}
否则{
返回(
更新删除
)
}
}
render(){
返回(
this.setState({name:e.target.value})}
/>
$this.setState({value:e.target.value})}
/>
{this.handleButtons()}
);
}
};
导出默认ChildComp;
我的最终目标是,在单击save(handleSubmit())或delete(handleDelete())按钮后,父组件重新呈现表或整个组件。抱歉,如果我发布了很多代码,我对JavaScript还是非常陌生,因此我仍然在了解相关信息。
谢谢你的意见

最简单的解决方案是调用setState()。 您只需在handleSubmit和handleDelete方法中添加这个.setState()调用。像一个

handleSubmit(){
    this.PostData();
    this.props.action();
    this.setState({something:something})
  }

每次调用setState组件时(重新渲染)

都可以从子级调用parent方法来重新渲染整个父级

父母

在submit/delete中获得API结果后,调用get data


另外,请避免使用
key={Math.random()}
而使用数据库ID作为键。

好的,我知道您想要什么,这很容易。在子组件中添加一个额外的道具

class ParentComp extends Component{
 state={
   something:null
 }
reloadTable=()=>{
   this.setState(something:something);
} 
render(){ 
   return(
      <ChildComp actionForReloadTable={this.reloadTable}....></ChildComp>
     ) 
}

仅出于学习目的,handleSubmit位于子组件中,因此更改状态不会强制子组件重新渲染,而不会强制父组件重新渲染吗?我现在就试试!我只是尝试了一下,我的假设是正确的,这只会导致childComp重新渲染,而不是整个表。谢谢你的建议!这是一个有趣的结果。这似乎是导致重新渲染的原因,但它导致重新渲染的速度很快。如果我执行两个操作,第二个操作将允许前一个操作渲染。这是因为它是在get/post/delete axios调用完成之前渲染的吗?
 axios.post("tableData/", payload, header)
            .then(response => {
                console.log(response);
                this.props.getData ()
              })
            .catch(error => {
              console.log(error);
        })
class ParentComp extends Component{
 state={
   something:null
 }
reloadTable=()=>{
   this.setState(something:something);
} 
render(){ 
   return(
      <ChildComp actionForReloadTable={this.reloadTable}....></ChildComp>
     ) 
}
handleSubmit(){
  this.PostData();
  this.props.action();
  this.props.actionForReloadTable();
}